SQL Server - برنامج نصي لتحديث أعمدة قاعدة البيانات من varchar إلى nvarchar إذا لم يكن nvarchar بالفعل
-
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'
ومع ذلك، هناك زوجان سريعان تحفظات لك.
- هذا سوف يفعل الجداول فقطستحتاج إلى فحص جميع sprocs والوظائف الخاصة بك للتأكد من تغييرها
NVARCHAR
أيضًا. - اذا كان لديك
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