如何将money和s​​mallmoney的所有SQL列更改为十进制?

时间:2017-01-05 11:14:31

标签: sql sql-server tsql

我尝试使用this question的答案将其修改为以下内容,但我收到了错误:

fetch next from maxcols into @schema, @table, @col, @dtype
  

Msg 8114,Level 16,State 5,Line 25
  将数据类型nvarchar转换为十进制时出错。

代码:

declare @schema nvarchar(255)
declare @table nvarchar(255)
declare @col nvarchar(255)
declare @dtype decimal(19,8)
declare @sql nvarchar(max)

declare maxcols cursor for
    select
        c.TABLE_SCHEMA, c.TABLE_NAME,
        c.COLUMN_NAME, c.DATA_TYPE
    from
        INFORMATION_SCHEMA.COLUMNS c
    inner join 
        INFORMATION_SCHEMA.TABLES t on c.TABLE_CATALOG = t.TABLE_CATALOG
                                    and c.TABLE_SCHEMA = t.TABLE_SCHEMA
                                    and c.TABLE_NAME = t.TABLE_NAME
                                    and t.TABLE_TYPE = 'BASE TABLE'
    where
        c.DATA_TYPE like '%money'

open maxcols

fetch next from maxcols into @schema, @table, @col, @dtype

while @@FETCH_STATUS = 0
begin
    set @sql = 'alter table [' + @schema + '].[' + @table + 
        '] alter column [' + @col + '] ' + @dtype
    exec sp_executesql @sql

    fetch next from maxcols into @schema, @table, @col, @dtype
end

close maxcols
deallocate maxcols

1 个答案:

答案 0 :(得分:3)

一些变化:

声明SYSNAME类型的@dtype变量并指定要使用的数据类型字符串,在您的情况下,它将是字符串'decimal(19,8)。您声明了decimal(19,8)数据类型的变量,这不是您想要的。

你应该真正声明SYSNAME类型的所有变量,它将用于保存SQL Server对象名,模式,表,列名等。

此外,在您的游标选择中,您不需要使用数据类型,它将在游标的select语句的where子句中被过滤掉。所以我从select {和Fetch next into行中取出了数据类型列。

还可以使用QUOTENAME()函数在对象名称周围添加sqaure括号。

declare  @table     SYSNAME
      ,  @col       SYSNAME 
      ,  @dtype     SYSNAME = 'decimal(19,8)'  --<-- Declare variable of sysname type
      ,  @sql       NVARCHAR(MAX) 
      ,  @schema    SYSNAME;

    declare maxcols cursor for
    select
        c.TABLE_SCHEMA,
        c.TABLE_NAME,
        c.COLUMN_NAME
    from
    INFORMATION_SCHEMA.COLUMNS c
    inner join INFORMATION_SCHEMA.TABLES t on
        c.TABLE_CATALOG = t.TABLE_CATALOG
        and c.TABLE_SCHEMA = t.TABLE_SCHEMA
        and c.TABLE_NAME = t.TABLE_NAME
        and t.TABLE_TYPE = 'BASE TABLE'
    where
        c.DATA_TYPE like '%money'

    open maxcols

    fetch next from maxcols into @schema, @table, @col

    while @@FETCH_STATUS = 0
    begin
        set @sql = N' alter table ' + QUOTENAME(@schema) + '.' + QUOTENAME(@table) 
                 + N' alter column ' + QUOTENAME(@col) + ' ' + @dtype

        exec sp_executesql @sql

        fetch next from maxcols into @schema, @table, @col
    end

    close maxcols
    deallocate maxcols