将所有VARCHAR列更改为NVARCHAR

时间:2015-06-11 05:41:05

标签: sql-server

我的数据库中有大约200列VARCHAR类型,无法存储卢比符号。现在我必须将所有列的数据类型从VARCHAR更改为NVARCHAR

有谁能告诉我完成这个的简短方法?为什么VARCHAR支持英镑符号而不支持卢比符号?我问,因为我必须将英镑符号更改为卢比符号。

6 个答案:

答案 0 :(得分:4)

您可以使用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'

从上面的查询中,您希望生成一个动态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)

答案 1 :(得分:0)

SELECT 'ALTER TABLE' +QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+ 'ALTER COLUMN ' + COLUMN_NAME + ' NVARCHAR(100)'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'TAbleName'

答案 2 :(得分:0)

通常在sqlserver中VARCHAR数据类型只允许 ANSI 字符,但NVARCHAR允许 UNICODE 字符集,Pound符号(156-ascii)数字),$符号是ANSI字符集。

所以VARCHAR允许这些。

但是当你来到最近发明的卢比符号所以它采用 UNICODE 字符集时,为了达到卢比符号,我们需要使用卢比字体或字形......   希望你明白y Pound是VARCHAR而卢比来自NVARCHAR ......

答案 3 :(得分:0)

这将循环遍历所有表及其列,并将生成查询以更新数据类型为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

答案 4 :(得分:0)

我今天遇到了这个问题,Felix的回答非常有效,但有一个例外-如果该列已定义默认值。我做了一些研究,提出了以下脚本,该脚本删除并恢复了默认值。

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)

答案 5 :(得分:0)

如果需要包括模式,请添加到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)