Frage

Ich habe voller datetime2 Spalten eine Datenbank bekam als Anforderungen an eine SQL 2005-Datenbank verschoben werden. Also, ich brauche alle diese datetime2 (7) Spalten in Datetime zu konvertieren.

Wie kann ich tun, um dies zu tun?

Im Moment habe ich es geschafft, den Tabellennamen und Spaltennamen für alle Spalten mit dem datetime2 Datentyp wie folgt wählen:

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'

Ich weiß nur nicht, wie Sie den Rest tun.

War es hilfreich?

Lösung

... dann iterieren Sie Ihre Ergebnisse mit den Cursor über und dynamisch die DDL ausführen wie:

ALTER TABLE myTable ALTER COLUMN myColumn datetime [NOT] NULL

, so dass Sie bekommen etwas ähnlich wie diese (nicht getestet):

Edit: hat null-Fähigkeit geprüft, auch:

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;

Andere Tipps

Ich weiß, dieser Thread ist alt, aber ich bin die gleiche Sache heute zu tun und wollte nur meine Technik opfern. Jedes Mal, wenn ich brauche eine Menge von DDL-Anweisungen zu tun, erstelle ich einen T-SQL, die die T-SQL erzeugt, das benötigt wird und dann nur die Ergebnisse in das Abfragefenster kopieren und ausführen. Sie müssen nicht alle den Cursor Code wie @van Vorschlag schreiben (obwohl das funktioniert gut).

Also, für Ihre Situation, führen Sie einfach die SQL-Anweisung:

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

Kopieren Sie dann die Ergebnisse in ein neues Abfragefenster und führen Sie es. Manchmal müssen Sie "GO" Aussagen auf ihre eigene Linie zwischen den Befehlen hinzuzufügen. Wenn ja, fügen Sie char(13) + 'GO' in der Ausgabezeichenfolge.

Also, stellen Sie sicher, dass die Abfrage in SQL Mgmt Studio mit den laufen Option "Ergebnisse in Text" anstelle der "Ergebnisse zu Grid" Option.

Verbesserte die obige Antwort für Schemata gerecht zu werden

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;

erforderlich, um diese heute für alle Benutzertabellen in einem Schema zu tun, und war mit keinem der vorhandenen Antworten nicht zufrieden. Insbesondere hatte einige meiner Datums-Werte Standardwerte, die eigentlich niemand benötigt, aber ALTER TABLE-Befehle behindert. Also schrieb ich ein Skript, das nur diesen Standard fällt, und ändert dann die Spalten. Es bewahrt NULL-Zulässigkeit und können Namen behandeln Leerzeichen enthalten, Bindestriche usw. Achtung, es nicht die Standardwerte danach neu.

Wenn Sie in der gleichen Situation sind, können Sie diesen stabilen und getestet Skript verwenden, die auch dafür sorgt, dass es keine automatischen Kürzen des nvarchar (max) Variable verwendet, um die DDL-Anweisungen zu schreiben:

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

Es nutzt alte Syntax und Schematabellen, so dass es funktioniert von SQL Server Version 2008 (das ist die erste Unterstützung datetime2 war) bis 2016.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top