T-SQL:datetime2 유형의 모든 열에 대해 datatime2를 datetime으로 변환합니다.

StackOverflow https://stackoverflow.com/questions/1446775

  •  22-07-2019
  •  | 
  •  

문제

SQL 2005 데이터베이스로 이동해야 하는 것보다 datetime2 열로 가득 찬 데이터베이스가 있습니다.따라서 이러한 모든 datetime2(7) 열을 datetime으로 변환해야 합니다.

이 작업을 어떻게 수행할 수 있나요?

지금은 다음과 같이 datetime2 데이터 유형을 가진 모든 열에 대해 테이블 ​​이름과 열 이름을 선택했습니다.

SELECT t.name, c.name, i.DATA_TYPE
FROM sys.tables AS t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name
WHERE i.data_type = 'datetime2'

나머지는 어떻게 해야할지 모르겠습니다.

도움이 되었습니까?

해결책

... 그런 다음 커서와 함께 결과를 반복하고 DDL과 같은 동적으로 실행합니다.

ALTER TABLE myTable ALTER COLUMN myColumn datetime [NOT] NULL

이와 비슷한 것을 얻을 수 있도록 (테스트되지 않음) :

편집 : NULL 가능성 확인도 추가되었습니다.

DECLARE @SQL AS NVARCHAR(1024)
DECLARE @TBL AS NVARCHAR(255)
DECLARE @COL AS NVARCHAR(255)
DECLARE @NUL AS BIT
DECLARE CUR CURSOR FAST_FORWARD FOR
    SELECT  t.name, c.name, c.is_nullable
    FROM    sys.tables AS t
    JOIN    sys.columns c ON t.object_id = c.object_id
    JOIN    information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name
    WHERE   i.data_type = 'datetime2'
    ORDER BY t.name, c.name

OPEN CUR
FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @SQL = 'ALTER TABLE ' + @TBL + ' ALTER COLUMN ' + @COL + ' datetime' + (CASE WHEN @NUL=1 THEN '' ELSE ' NOT' END) + ' NULL;'
    EXEC sp_executesql @SQL
    FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
END

CLOSE CUR;
DEALLOCATE CUR;

다른 팁

나는이 스레드가 늙었다는 것을 알고 있지만 오늘도 같은 일을하고 있으며 내 기술을 제공하고 싶었습니다. 많은 DDL 문을 수행해야 할 때마다 필요한 TSQL을 생성하는 하나의 TSQL을 작성한 다음 결과를 쿼리 창에 복사하여 실행합니다. @van 제안과 같은 모든 커서 코드를 작성할 필요는 없습니다 (잘 작동하지만).

따라서 상황을 위해 SQL 문을 실행하십시오.

select 'ALTER TABLE ' + table_name + ' ALTER COLUMN ' + column_name + ' datetime [NOT] NULL' 
from INFORMATION_SCHEMA.columns 
where data_type = 'datetime2(7)'.

그런 다음 결과를 새 쿼리 창에 복사하여 실행하십시오. 때로는 추가해야합니다 "GO" 명령 사이의 자체 라인에 대한 진술. 그렇다면 추가하십시오 char(13) + 'GO' 출력 문자열로.

또한 "결과에 대한 결과"옵션 대신 "results to text"옵션을 사용하여 SQL MGMT Studio에서 쿼리를 실행하십시오.

스키마를 수용하는 위의 답변을 개선했습니다

DECLARE @SQL AS NVARCHAR(1024)
DECLARE @TBL AS NVARCHAR(255)
DECLARE @COL AS NVARCHAR(255)
DECLARE @SCH AS NVARCHAR(255)
DECLARE @NUL AS BIT
DECLARE CUR CURSOR FAST_FORWARD FOR
    SELECT  t.name AS TableName, c.name ColumnName, s.name AS SchemaName, c.is_nullable
    FROM    sys.tables AS t
    JOIN    sys.columns c ON t.object_id = c.object_id
    JOIN    information_schema.columns AS i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name
    JOIN    sys.schemas AS s on t.schema_id = s.schema_id
    WHERE   i.data_type = 'datetime2'    
    ORDER BY t.name, c.name

OPEN CUR
FETCH NEXT FROM CUR INTO @TBL, @COL, @SCH, @NUL
WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @SQL = 'ALTER TABLE ['+@SCH+'].[' + @TBL + '] ALTER COLUMN [' + @COL + '] datetime' + (CASE WHEN @NUL=1 THEN '' ELSE ' NOT' END) + ' NULL;'
    EXEC sp_executesql @SQL
    FETCH NEXT FROM CUR INTO @TBL, @COL,@SCH, @NUL
END

CLOSE CUR;
DEALLOCATE CUR;

오늘 스키마의 모든 사용자 테이블에 대해 이 작업을 수행해야 했지만 기존 답변이 만족스럽지 않았습니다.특히 내 날짜/시간 열 중 일부에는 기본값이 있어서 실제로는 아무도 필요하지 않았지만 ALTER TABLE 명령을 방해했습니다.그래서 저는 해당 기본값을 삭제하고 열을 변경하는 스크립트를 작성했습니다.null 허용 여부를 유지하고 공백, 하이픈 등이 포함된 이름을 처리할 수 있습니다.주의하세요. 나중에 기본값을 다시 생성하지 않습니다.

동일한 상황에 처한 경우 다음 안정적이고 테스트된 스크립트를 사용할 수 있습니다. 이 스크립트는 DDL 문을 작성하는 데 사용되는 nvarchar(max) 변수가 자동으로 잘리지 않는지 확인합니다.

DECLARE @sql AS nvarchar(max)=N''

--1. "ALTER TABLE [Tablename] DROP CONSTRAINT [DF__Tablename__Colname__Obfuscation]"
SELECT @sql=CAST('' AS nvarchar(MAX))+@sql 
  +N'ALTER TABLE ['+o.[name]+N'] DROP CONSTRAINT ['+co.[name]+']' 
FROM sysconstraints c 
INNER JOIN sysobjects o ON o.[id]=c.[id] 
INNER JOIN syscolumns col ON col.[id]=o.[id] AND col.colid=c.colid
INNER JOIN sysobjects co ON co.[id]=c.constid 
WHERE col.xtype=61 --datetime

EXEC sp_executesql @sql

--2. change type of all datetime columns
SELECT @sql=N''
SELECT @sql=CAST('' AS nvarchar(MAX))+@sql 
  +N'ALTER TABLE [' 
  +convert(nvarchar(max),t.name)
  +N'] ALTER COLUMN [' 
  +convert(nvarchar(max),c.name)
  +N'] datetime2 ' 
  +CASE WHEN c.is_nullable = 1 THEN N'' ELSE N'NOT' END
  +N' NULL;'+convert(nvarchar(max),char(13)+char(10))
FROM sys.tables t 
INNER JOIN sys.columns c ON t.object_id = c.object_id 
INNER JOIN sys.types st ON st.system_type_id = c.system_type_id
WHERE st.name=N'datetime'
AND t.xtype=N'U' --user tables only
ORDER BY t.[name]

EXEC sp_executesql @sql

고대 구문과 스키마 테이블을 사용하므로 SQL Server 버전 2008(최초로 지원한 버전)에서 작동합니다. datetime2) 2016년까지.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top