将列重命名为以前存在的具有不同类型的列将不允许我更新

时间:2014-03-18 14:21:23

标签: sql sql-server sql-server-2008 sql-server-2008-r2

背景:在我正在研究的Java应用程序中,我正在重构枚举值的存储。以前,这些存储为整数,并通过枚举值与枚举中的辅助方法进行映射。我想利用JPA的@ EnumType.STRING功能使数据库更具可读性。

所以,我基本上要做的是改变列的类型(以及值)。例如,我从这个表定义开始:

table Something (
    id int,
    source int,
    [more columns]
)

我想将源列更改为VARCHAR(100)列,而这就是我的做法:

  1. 使用VARCHAR(100)引入一个名为source_new的新列。
  2. 使用基于旧列值的映射值填充新列(因此源列中值为1的每一行获取source_new中的值'SomeSource',源中值为2的每行获取'OtherSource',等等。
  3. 删除源列
  4. 将source_new列重命名为source(使用sp_rename)
  5. 我的问题是:一旦完成,我就无法更新现在新定义的源列,因为它仍然坚持它是一个int列,而不是一个varchar列!

    这样的查询:

    update Something set source = 'SomeSource' where id = 1;
    

    失败了:

    Error: Conversion failed when converting the varchar value 'SomeSource' to data type int.
    SQLState:  22018
    ErrorCode: 245
    

    同时,表的sp_help显示该列被定义为varchar(100),而不是int!此外,该列包含来自原始数据迁移的许多varchar值(从重命名之前)。

    这是一个错误,还是我通过将列重命名为以前与其他类型一起使用的列名来做错? (当我输入最后一个问题时,对我来说这听起来很荒谬,当我删除一列我希望消失时,不留下痕迹,实际上不允许我在将来的任何时候重用列名。 。)

    用SQLFiddle来说明(sp_rename似乎不适用于SQLFiddle):http://sqlfiddle.com/#!3/0380f/3

1 个答案:

答案 0 :(得分:0)

我找到了罪魁祸首,它的名字就是触发器!

一些天才决定检查更新的值是否是触发器中的有效源(检查另一个表),以便信任您自己的代码..

我吐出了隐藏数据库触发器功能的人的阴影,pfoy!回到你所属的80年代! :P