我处于必须使用脚本将现有数据库结构从 varchar 更新为 nvarchar 的情况。由于每次运行配置应用程序时都会运行此脚本,因此我宁愿确定列是否已更改为 nvarchar 并且不对表执行更改。我必须支持的数据库是 SQL Server 2000、2005 和 2008。
Michelle
问问题
18740 次
5 回答
26
您可以运行以下脚本,该脚本将为您提供一组 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'
但是,有几个快速警告给您。
- 这只会做表。您需要扫描所有的存储过程和函数,以确保它们也被更改
NVARCHAR
为。 - 如果您有
VARCHAR
> 4000,则需要将其修改为NVARCHAR(MAX)
但是使用这个模板应该很容易做到。
如果您希望它自动运行,您可以在WHILE
子句中设置它。
于 2008-10-07T20:11:02.890 回答
4
约瑟夫回答的问题是它会在执行查询后将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
归功于伊戈尔的回答
于 2015-08-05T08:19:46.823 回答
2
以下查询应该可以满足您的需求:
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
于 2008-10-07T19:41:37.630 回答
2
修复了空间问题并添加了架构
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'
于 2012-11-20T07:31:05.430 回答
0
进一步更新以修复 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
归功于Nezam的回答
另一个管理默认值:
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
于 2019-02-28T19:05:19.960 回答