SQL Server - برنامج نصي لتحديث أعمدة قاعدة البيانات من varchar إلى nvarchar إذا لم يكن nvarchar بالفعل

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

  •  05-07-2019
  •  | 
  •  

سؤال

أنا في موقف حيث يجب علي تحديث بنية قاعدة بيانات موجودة من varchar إلى nvarchar باستخدام برنامج نصي.نظرًا لأنه يتم تشغيل هذا البرنامج النصي في كل مرة يتم فيها تشغيل تطبيق التكوين، أفضل تحديد ما إذا كان العمود قد تم تغييره بالفعل إلى nvarchar وعدم إجراء تغيير على الجدول.قواعد البيانات التي يجب أن أدعمها هي SQL Server 2000 و2005 و2008.

هل كانت مفيدة؟

المحلول

والاستعلام التالي يجب أن تحصل على ما تحتاج إليه:

IF EXISTS 
  (SELECT *
   FROM sysobjects syo
   JOIN syscolumns syc ON
     syc.id = syo.id
   JOIN systypes syt ON
     syt.xtype = syc.xtype
   WHERE 
     syt.name = 'nvarchar' AND
     syo.name = 'MY TABLE NAME' AND
     syc.name = 'MY COLUMN NAME')
BEGIN
   ALTER ...
END

نصائح أخرى

يمكنك تشغيل البرنامج النصي التالي الذي سيعطيك مجموعة من أوامر ALTER:

SELECT 'ALTER TABLE ' + isnull(schema_name(syo.id), 'dbo') + '.' +  syo.name 
    + ' ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.length when -1 then 'MAX' 
        ELSE convert(nvarchar(10),syc.length) end + ');'
   FROM sysobjects syo
   JOIN syscolumns syc ON
     syc.id = syo.id
   JOIN systypes syt ON
     syt.xtype = syc.xtype
   WHERE 
     syt.name = 'varchar' 
    and syo.xtype='U'

ومع ذلك، هناك زوجان سريعان تحفظات لك.

  1. هذا سوف يفعل الجداول فقطستحتاج إلى فحص جميع sprocs والوظائف الخاصة بك للتأكد من تغييرها NVARCHAR أيضًا.
  2. اذا كان لديك VARCHAR > 4000 سوف تحتاج إلى تعديله ليكون NVARCHAR(MAX)

ولكن يجب أن يكون ذلك ممكنًا بسهولة باستخدام هذا القالب.

إذا كنت تريد أن يتم تشغيل هذا تلقائيًا، فيمكنك ضبطه في ملف WHILE بند.

المشكلة في إجابة جوزيف هي أنها ستتغير NOT NULL الحقول الى NULL بعد تنفيذ الاستعلامات.التلاعب التالي يعمل على إصلاحه:

SELECT cmd = 'alter table [' + c.table_schema + '].[' + c.table_name 
 + '] alter column [' + c.column_name + '] nvarchar('
 +CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000
       THEN CAST(CHARACTER_MAXIMUM_LENGTH as varchar(10)) ELSE 'max' END+')' 
 + CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END,*
FROM information_schema.columns c
WHERE c.data_type='varchar' 
ORDER BY CHARACTER_MAXIMUM_LENGTH desc

الشكر ل إجابة ايجور

وثابت مسألة الفضاء ومخطط وأضاف

SELECT 'ALTER TABLE [' + isnull(schema_name(syo.object_id), sysc.name) + '].[' +  syo.name 
    + '] ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.max_length when -1 then 'MAX' 
        ELSE convert(nvarchar(10),syc.max_length) end + ');'
   FROM sys.objects syo
   JOIN sys.columns syc ON
     syc.object_id= syo.object_id
   JOIN sys.types syt ON
     syt.system_type_id = syc.system_type_id
    JOIN sys.schemas sysc ON
    syo.schema_id=sysc.schema_id
   WHERE 
     syt.name = 'varchar' 
    and syo.type='U'

وتحديثها بالإضافة إلى إصلاح MAX يتم استبداله مع -1.

SELECT cmd = 'ALTER TABLE [' + c.table_schema + '].[' + c.table_name 
 + '] ALTER COLUMN [' + c.column_name + '] NVARCHAR('
 +CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000 THEN 
 CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
 'MAX' ELSE CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) END ELSE 'MAX' END+')' 
 + CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END,*
FROM information_schema.columns c
WHERE c.data_type='VARCHAR' 
ORDER BY CHARACTER_MAXIMUM_LENGTH DESC

الإجابة نظيم و

واحد آخر لإدارة القيم الافتراضية:

SELECT cmd = 
CASE WHEN name IS NOT NULL THEN
    'ALTER TABLE ' + c.table_name + ' DROP CONSTRAINT ' + d.name + '; ' +
    'ALTER TABLE [' + c.table_schema + '].[' + c.table_name + '] ALTER COLUMN [' + c.column_name + '] ' + 
    'NVARCHAR(' +
    CASE WHEN CHARACTER_MAXIMUM_LENGTH <= 4000 THEN 
        CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
            'MAX' 
        ELSE 
            CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) 
        END 
     ELSE 
        'MAX' 
    END 
    + ')' +
    CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END + '; ' + 
    'ALTER TABLE '+ c.table_name + ' ADD CONSTRAINT ' + d.name +' DEFAULT '+ c.column_default + ' FOR ' + c.column_name + ';'
ELSE
    'ALTER TABLE [' + c.table_schema + '].[' + c.table_name + '] ALTER COLUMN [' + c.column_name + '] ' +
    'NVARCHAR(' +
    CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000 THEN
        CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
            'MAX' 
        ELSE 
            CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) 
        END 
    ELSE 
        'MAX' 
    END
    + ')' +
    CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END 
END,d.name, c.*
FROM information_schema.columns c
LEFT OUTER JOIN sys.default_constraints d ON d.parent_object_id = object_id(c.table_name)
AND d.parent_column_id = columnproperty(object_id(c.table_name), c.column_name, 'ColumnId')
WHERE c.data_type='VARCHAR' 
ORDER BY CHARACTER_MAXIMUM_LENGTH DESC
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top