تي إس كيو إل:تحويل datatime2 إلى datetime لجميع الأعمدة من النوع datetime2

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

  •  22-07-2019
  •  | 
  •  

سؤال

لدي قاعدة بيانات مليئة بأعمدة datetime2 التي يجب نقلها إلى قاعدة بيانات SQL 2005.لذا، أحتاج إلى تحويل كل أعمدة 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

حتى تحصل على شيء مشابه لهذا (لم يتم اختباره):

يحرر:تمت إضافة فحص القدرة الخالية أيضًا:

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 I إنشاء 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' الإخراج الخاص بك.

وبالإضافة إلى ذلك، تأكد من تشغيل الاستعلام في SQL إدارةالمبيعات ستوديو مع "النتائج إلى نص" الخيار بدلا من "نتائج الشبكة إلى" الخيار.

وتحسين الجواب أعلاه لتلبية احتياجات المخططات

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;

وهناك حاجة للقيام بذلك اليوم لكافة الجداول المستخدم في مخطط، وكان غير راض عن أي من الإجابات الموجودة. خاصة، وكان بعض من أعمدة التاريخ والوقت بلدي التخلف، والتي في الواقع حاجة أحد، ولكن أعاقت الأوامر TABLE ALTER. لذلك كتبت السيناريو الذي يسقط فقط تلك الافتراضات، وتغيير الأعمدة ثم. أنه يحفظ nullability، ويمكن التعامل مع الأسماء التي تحتوي على مسافات، الواصلات الخ الحذر، فإنه لا إعادة إنشاء الإعدادات الافتراضية بعد ذلك.

إذا كنت في نفس الوضع، يمكنك استخدام هذا البرنامج النصي مستقر واختبارها، الأمر الذي يجعل أيضا من أن ليس هناك اقتطاع صامت للNVARCHAR (حد أقصى) متغير يستخدم لتكوين البيانات DDL:

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