none
SQLSERVER BUG ? NO! RRS feed

  • 问题

  • if not exists(SELECT * FROM syscolumns WHERE name = N'BBDA_SB' AND id =Object_id (N'bbda'))

    begin

       alter table bbda add  BBDA_SB varchar(1) default '0' 

       UPDATE bbda SET BBDA_SB='0'

    end

    Microsoft SQL Server Management Studio      9.00.1399.00
    Microsoft Analysis Services 客户端工具      2005.090.1399.00
    Microsoft 数据访问组件 (MDAC)      2000.086.1830.00 (srv03_sp1_rtm.050324-1447)
    Microsoft MSXML      2.6 3.0 4.0 5.0 6.0
    Microsoft Internet Explorer      6.0.3790.1830
    Microsoft .NET Framework      2.0.50727.1433
    操作系统      5.2.3790

    此版本的sql2005可以执行.

    但是

    Microsoft SQL Server Management Studio                                                    9.00.3042.00

    Microsoft Analysis Services 客户端工具                                                      2005.090.3042.00

    Microsoft 数据访问组件 (MDAC)                                                       2000.086.3959.00 (srv03_sp2_rtm.070216-1710)

    Microsoft MSXML                                                  2.6 3.0 6.0

    Microsoft Internet Explorer                                                   6.0.3790.3959

    Microsoft .NET Framework                                                    2.0.50727.42

    操作系统                                                        5.2.3790

    这个版本的sql2005及sql2008不能执行此sql,

    难道是sqlserver不向下兼容?


    scott
    • 已移动 Leo Liu - MSFT 2011年1月14日 9:35 Off-Topic, moved for better support. (发件人:Visual C#)
    • 已编辑 www_scott 2011年1月27日 3:08
    2011年1月12日 1:58

答案

  • 这个不是bug,by design。

    更新表结构的时候会产生架构修改锁(SCH-M),这个锁不兼容任何其他类型锁(排他),在事务完成之前,不能更新这个表内数据。

    因此新版本中修改结构和更新数据的语句不能在同一个事务中执行了,必须分开。

     


    family as water
    • 已标记为答案 Mog Liang 2011年2月1日 2:11
    2011年1月26日 14:07

全部回复

  • 错误信息:

    消息207,级别16,状态1,第4

    Invalid column name 'BBDA_SB'.


    scott
    2011年1月12日 2:25
  • 从错误上看应该是无效的列名。先去数据库看看这个列是否存在,如果存在的话,把 UPDATE 语句和 ALTER 用 GO 分开。
    Mark Zhou
    2011年1月12日 9:03
  • 能分开早分开了,分开是可以的,但是逻辑不对。现在就是问是MS bug,还是就是不行
    scott
    2011年1月12日 9:52
  • SELECT * FROM syscolumns WHERE name = N'BBDA_SB' AND id =Object_id (N'bbda')

    改成 [name] 试试

    2011年1月14日 9:06
  • 非BUG

     

    if not exists(SELECT * FROM syscolumns WHERE name = N'BBDA_SB' AND id =Object_id (N'bbda'))

     alter table bbda add  BBDA_SB varchar(1) default '0' 

    Go

    UPDATE bbda SET BBDA_SB='0' Where BBDA_SB is Null

    **防止已经有此字段及值

     

    读下SQL机制吧,这是它的正确逻辑



    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com
    2011年1月15日 2:49
  • 非bug,那为什么有的版本是可以执行的?sqlserver是向下兼容还是向上兼容?

    另外,我要的就是那个逻辑,如果不存此列,我添加此列,然后更新此列默认值。如果拆开就不对了(没有此列我添加此列,并且都要更新此列的默认值),如果有的用户此列的默认已经更改了。那我再更新此列,起不造成数据错误。


    scott
    2011年1月17日 8:20
  • 你可以建个表,设一个值,当有Add column时,就更新此值标志

    在GO后再判断这个标志Update


    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com
    2011年1月18日 4:32
  • 微软bug
    scott
    2011年1月21日 6:39
  • 看起来像一个bug (regression)。SQL Server 2008也是这个行为。用下面的workaround,避可以免这个编译检查错误。

    if not exists(SELECT * FROM syscolumns WHERE name = N'BBDA_SB' AND id =Object_id (N'bbda'))

    begin

       alter table bbda add  BBDA_SB varchar(1) default '0' 

       EXEC('UPDATE bbda SET BBDA_SB=''0''')

    end

     

    2011年1月26日 10:44
  • 这个不是bug,by design。

    更新表结构的时候会产生架构修改锁(SCH-M),这个锁不兼容任何其他类型锁(排他),在事务完成之前,不能更新这个表内数据。

    因此新版本中修改结构和更新数据的语句不能在同一个事务中执行了,必须分开。

     


    family as water
    • 已标记为答案 Mog Liang 2011年2月1日 2:11
    2011年1月26日 14:07
  • 我试了SQL 2005 RTM也不行。正如楼上所说,这个是by design,不是bug。可以用EXEC('update...')处理,修改程序。

    运行select @@version 看看你的SQL Server是什么版本?

    2011年1月27日 2:35
  • 正是,我现在就是利用EXEC处理的,谢谢各位


    scott
    2011年1月27日 3:03
  • 也可以利用WITH VALUES,这样就不需要update语句了,一个语句搞定。

     

       alter table bbda add  BBDA_SB varchar(1) default '0' WITH VALUES

     

    2011年1月28日 7:14