T-SQL:datetime2 유형의 모든 열에 대해 datatime2를 datetime으로 변환합니다.
문제
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년까지.