有没有人看到SQL Server的这段代码有什么问题?
IF NOT EXISTS(SELECT *
FROM sys.columns
WHERE Name = 'OPT_LOCK'
AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
BEGIN
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ADD OPT_LOCK NUMERIC(10, 0)
UPDATE REP_DSGN_SEC_GRP_LNK
SET OPT_LOCK = 0
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
END;
当我运行这段代码时,我得到:
消息207,第16级,状态1,第3行
无效的列名'OPT_LOCK‘。
在更新命令上。
谢谢。
发布于 2012-09-22 01:40:22
在这种情况下,可以通过将列添加为NOT NULL
并在一个语句as per my answer here中设置现有行的值来避免这个问题。
更广泛地说,这个问题是一个解析/编译问题。SQL Server尝试在执行任何语句之前编译批处理中的所有语句。
当一条语句引用了一个根本不存在的表时,该语句将受到延迟编译的影响。当表已经存在时,如果引用了不存在的列,则会抛出错误。解决这个问题的最好方法是在与DML不同的批处理中执行DDL。
如果语句同时引用了现有表和不存在的表中不存在的列,则在延迟编译之前可能会抛出错误,也可能不会抛出错误。
您可以在单独的批次中提交它(例如,使用客户端工具中的批次分隔符GO
),或者在使用EXEC
或EXEC sp_executesql
单独编译的子范围内执行它。
第一种方法要求您重构代码,因为IF ...
不能跨批处理。
IF NOT EXISTS(SELECT *
FROM sys.columns
WHERE Name = 'OPT_LOCK'
AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
BEGIN
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ADD OPT_LOCK NUMERIC(10, 0)
EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0');
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
END;
发布于 2020-07-29 05:32:32
使用Go命令和默认值0来解决此问题。
--Add all columns, if they don't exist
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0
ALTER TABLE REP_DSGN_SEC_GRP_LNK
ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
GO
--Consume new columns
UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 1 WHERE SOMETHING = 'ELSE'
GO
发布于 2020-02-21 04:42:23
该错误的根本原因是,在重新启动SQL Server Management Studio之前,新添加的列名不会反映在sys.syscolumns和sys.columns表中。
https://stackoverflow.com/questions/12535405
复制相似问题