[英]Change all VARCHAR columns to NVARCHAR
I have about 200 columns in my database with VARCHAR
type which is unable to store the rupee symbol.我的数据库中有大约 200 列VARCHAR
类型无法存储卢比符号。 Now I have to change the datatype of all the columns from VARCHAR
to NVARCHAR
.现在我必须将所有列的数据类型从VARCHAR
更改为NVARCHAR
。
Can anyone please tell me the short way to accomplish this?谁能告诉我实现这一目标的捷径? And why does the VARCHAR
support the pound sign and not the rupee sign?为什么VARCHAR
支持英镑符号而不支持卢比符号? I'm asking because I have to change the pound symbol to rupee symbol.我问是因为我必须将英镑符号更改为卢比符号。
You can view all the columns, their data types and the table they belong using the ff query:您可以使用 ff 查询查看所有列、它们的数据类型和它们所属的表:
SELECT
t.name AS table_name,
c.name AS column_name,
tp.name AS data_type,
c.max_length,
c.is_nullable
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.types tp
ON tp.user_type_id = c.user_type_id
WHERE tp.name = 'varchar'
From the query above, you want to generate a dynamic sql that will change all your VARCHAR
columns to NVARCHAR
.从上面的查询中,您希望生成一个动态 sql,它将所有VARCHAR
列更改为NVARCHAR
。
DECLARE @sql AS VARCHAR(MAX) = ''
SELECT @sql = @sql
+ 'ALTER TABLE ' + table_name
+ ' ALTER COLUMN ' + column_name + ' NVARCHAR('
+ CASE WHEN max_length <> - 1 THEN CAST(max_length AS VARCHAR(10)) ELSE 'MAX' END + ')'
+ CASE WHEN is_nullable = 1 THEN ' NULL' ELSE '' END
+ ';' + CHAR(10)
FROM (
SELECT
t.name AS table_name,
c.name AS column_name,
tp.name AS data_type,
c.max_length,
c.is_nullable
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.types tp
ON tp.user_type_id = c.user_type_id
WHERE tp.name = 'varchar'
)t
PRINT @sql
EXEC(@sql)
I met this issue today and Felix's answer worked quite well with one exception- if the column has default value defined.我今天遇到了这个问题,Felix 的回答非常有效,但有一个例外——如果该列定义了默认值。 I researched a little bit and came up with the following script that drops and restores the default value.我研究了一下,想出了下面的脚本来删除和恢复默认值。
DECLARE @sql AS VARCHAR(MAX) = ''
SELECT @sql = @sql
+ CASE WHEN default_id>0 THEN 'ALTER TABLE '+table_name+' DROP CONSTRAINT '+OBJECT_NAME(default_id) +';'+CHAR(10) ELSE '' END
+ 'ALTER TABLE ' + table_name
+ ' ALTER COLUMN ' + column_name + ' NVARCHAR('
+ CASE WHEN (max_length <> - 1 AND max_length<4001) THEN CAST(max_length AS VARCHAR(10)) ELSE 'MAX' END + ')'
+ CASE WHEN is_nullable = 1 THEN ' NULL' ELSE '' END
+ ';' + CHAR(10)
+ CASE WHEN default_id>0 THEN 'ALTER TABLE '+table_name+' ADD DEFAULT '+default_value+' FOR '+column_name +';'+CHAR(10) ELSE '' END
FROM (
SELECT
t.name AS table_name,
c.name AS column_name,
tp.name AS data_type,
c.max_length,
c.default_object_id AS default_id,
OBJECT_DEFINITION(c.default_object_id) AS default_value,
c.is_nullable
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.types tp
ON tp.user_type_id = c.user_type_id
WHERE tp.name = 'varchar'
)t
PRINT @sql
EXEC(@sql)
Normally in sqlserver VARCHAR
datatype allows only the ANSI Characters, But NVARCHAR
allows UNICODE Character sets also, Pound symbol(156-ascii number), $ symbols are comes under ANSI character set.通常在 sqlserver 中, VARCHAR
数据类型只允许ANSI字符,但NVARCHAR
允许UNICODE字符集,磅符号(156-ascii 数字),$ 符号属于 ANSI 字符集。
So VARCHAR
allows those.所以VARCHAR
允许这些。
But when u comes to the Rupee Symbol its recently invented so it comes under UNICODE character set, to achieve the rupee symbol we need to use rupees font or glyphs... Hope you understood y Pound comes under VARCHAR
and Rupee Comes under NVARCHAR
...但是当你谈到最近发明的卢比符号时,它属于UNICODE字符集,为了实现卢比符号,我们需要使用卢比字体或字形......希望你明白 y 英镑属于VARCHAR
和卢比属于NVARCHAR
.. .
Adding on to Felix Pamittan's answer if you need to include schema.如果您需要包含架构,请添加到 Felix Pamittan 的答案中。
DECLARE @sql AS VARCHAR(MAX) = ''
SELECT @sql = @sql
+ 'ALTER TABLE ' + table_schema_name + '.' + table_name
+ ' ALTER COLUMN ' + column_name + ' NVARCHAR('
+ CASE WHEN max_length <> - 1 THEN CAST(max_length AS VARCHAR(10)) ELSE 'MAX' END + ')'
+ CASE WHEN is_nullable = 1 THEN ' NULL' ELSE '' END
+ ';' + CHAR(10)
FROM (
SELECT
sc.name AS table_schema_name,
t.name AS table_name,
c.name AS column_name,
tp.name AS data_type,
c.max_length,
c.is_nullable
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.types tp
ON tp.user_type_id = c.user_type_id
INNER JOIN sys.schemas sc
ON sc.schema_id = t.schema_id
WHERE tp.name = 'varchar'
)t
PRINT @sql
EXEC(@sql)
SELECT 'ALTER TABLE' +QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+ 'ALTER COLUMN ' + COLUMN_NAME + ' NVARCHAR(100)'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'TAbleName'
This will loop through all tables and their columns, and will generate query for updating those which have datatype as varchar
这将遍历所有表及其列,并将生成查询以更新数据类型为varchar
那些
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @Length nvarchar(128)
SET @TableName = ''
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SELECT @ColumnName=MIN(QUOTENAME(COLUMN_NAME)),@Length=MIN(CHARACTER_MAXIMUM_LENGTH)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
--AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND DATA_TYPE IN ('varchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
IF @ColumnName IS NOT NULL and @Length > 0
BEGIN
print (' ALTER TABLE ' +@TableName+ ' ALTER COLUMN ' + @ColumnName + ' NVARCHAR('+@Length+')')
--exec (@dSql)
END
END
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.