none
修改表列为空同时创建关键索引出错,但在其中用GO隔开就可以,为何? RRS feed

  • 问题

  • 在SQL SERVER 2000中

    ALTER TABLE [dbo].[attrecord] alter column phyid numeric(12,0) not null
    go
     aLTER TABLE [dbo].[attrecord] WITH NOCHECK ADD  CONSTRAINT [PK_attrecord] PRIMARY KEY  CLUSTERED
     (
      [phyid]
     )  ON [PRIMARY]

    不用GO隔开就会出现以下错误:

    消息 8111,级别 16,状态 1,第 3 行
    无法在表 'attrecord' 中可为空的列上定义 PRIMARY KEY 约束。
    消息 1750,级别 16,状态 0,第 3 行
    未能创建约束。请参阅前面的错误信息。

    2020年11月11日 8:30

答案

  • 你好,

    GO命令表明应用程序(如SSMS, sqlcmd)向SQL Server发送批量T-SQL 语句已结束的信号。

    在您的问题中,报错信息显示"无法在表 'attrecord' 中可为空的列上定义 PRIMARY KEY 约束"。这是因为如果在您的上述t-sql语句中不使用GO,那么两条修改命令将会以一个批语句发给SQL Server进行处理,这样实际上在这个批语句处理完成之前,第一个修改并未实际执行该字段仍然可为空,然后第二个修改由于在可为空的列上定义约束引发了错误导致语句执行失败。

    如果用GO命令隔开您的t-sql语句,那么SSMS将会发送两个批语句给SQL Server处理,所以不会出现问题。

    可以参考官方文档了解更多—SQL Server 实用工具语句 - GO.

    另外你的SQL Server版本是2000,我在2019上测试同样是这样的情况。这是设计使然。

    *****************************************************

    如果您已解决问题,请将有用的答复标记为答案。 这可能对其他遇到类似问题的社区成员有帮助。
    此外,如果您还有其他问题,请随时提出。

    2020年11月11日 9:50

全部回复

  • 你好,

    GO命令表明应用程序(如SSMS, sqlcmd)向SQL Server发送批量T-SQL 语句已结束的信号。

    在您的问题中,报错信息显示"无法在表 'attrecord' 中可为空的列上定义 PRIMARY KEY 约束"。这是因为如果在您的上述t-sql语句中不使用GO,那么两条修改命令将会以一个批语句发给SQL Server进行处理,这样实际上在这个批语句处理完成之前,第一个修改并未实际执行该字段仍然可为空,然后第二个修改由于在可为空的列上定义约束引发了错误导致语句执行失败。

    如果用GO命令隔开您的t-sql语句,那么SSMS将会发送两个批语句给SQL Server处理,所以不会出现问题。

    可以参考官方文档了解更多—SQL Server 实用工具语句 - GO.

    另外你的SQL Server版本是2000,我在2019上测试同样是这样的情况。这是设计使然。

    *****************************************************

    如果您已解决问题,请将有用的答复标记为答案。 这可能对其他遇到类似问题的社区成员有帮助。
    此外,如果您还有其他问题,请随时提出。

    2020年11月11日 9:50
  • 你好,

    如果您已解决问题,请将有用的答复标记为答案。 这可能对其他遇到类似问题的社区成员有帮助。
    此外,如果您还有其他问题,请随时提出。

    2020年11月16日 2:10
  • 但GO不能写在存储过程中。如果在存储过程中写如何办?
    2020年12月24日 8:46
  • Try end statement with ';'.
    2020年12月25日 0:31
  • 通常,提交由GO分隔的单独批处理的另一种方法是使用EXEC在子批处理中执行SQL。我测试如下例子是可行的。
    CREATE PROCEDURE dbo.test_pro
    AS
    declare @sql1 varchar(max)
    select @sql1 = 'ALTER TABLE [dbo].[student] alter column phyid numeric(10,0) not null'
    declare @sql2 varchar(max)
    select @sql2 = 'ALTER TABLE [dbo].[student] WITH NOCHECK ADD  CONSTRAINT [PK_attrecord] PRIMARY KEY  CLUSTERED ([phyid])'
    exec (@sql1);
    exec (@sql2);
    GO 


    2020年12月25日 5:38