刷新对表的 DDL 更改

Jac*_*ock 3 sql-server t-sql sql-server-2012

我正在尝试创建巨型脚本,通过添加/删除/修改现有数据库的列来更新一堆表。困扰我的一个问题是,每当我在一个语句的表中添加新列并尝试在另一条语句中引用它时,它都会失败并显示关于无效列 xxx 的错误。

以下是我用来重现此问题的伪代码,

--CREATE TABLE testTable (u_id int, u_name varchar(10))
--INSERT INTO testTable VALUES (1,'11')
--INSERT INTO testTable VALUES (2,'12')
--INSERT INTO testTable VALUES (3,'13')
--INSERT INTO testTable VALUES (4,'14')
--INSERT INTO testTable VALUES (5,'15')

BEGIN
ALTER table testTable ADD u_add varchar(10)
END

BEGIN
CREATE TABLE tmp_xx_xx_testTable (u_id int, u_name varchar(10), u_add varchar(10))

INSERT INTO dbo.tmp_xx_xx_testTable VALUES (6,'16','DDD'  )

INSERT INTO tmp_xx_xx_testTable (u_id,u_name,u_add) 
SELECT u_id,u_name,u_add FROM TestTable

drop TABLE TestTable

EXECUTE sp_rename
                N'[dbo].[tmp_xx_xx_testTable]',
                N'TestTable';
END

--SELECT * FROM testTable
--DROP TABLE testable
Run Code Online (Sandbox Code Playgroud)

第一(也是最后)几行只是为了准备我正在使用的测试表。

当我运行此代码时,我收到一个关于列u_add无效的错误。但是当我单独运行相同的语句时,它们运行没有任何问题。所以看起来不知何故我不明白这里还需要做什么,所以SQL Server实际上可以“看到”新添加的列。

Han*_*non 6

在语句之间添加批处理分隔符。通常,选择的批处理分隔符是GO

--CREATE TABLE testTable (u_id int, u_name varchar(10))
--INSERT INTO testTable VALUES (1,'11')
--INSERT INTO testTable VALUES (2,'12')
--INSERT INTO testTable VALUES (3,'13')
--INSERT INTO testTable VALUES (4,'14')
--INSERT INTO testTable VALUES (5,'15')

BEGIN
ALTER table testTable ADD u_add varchar(10)
END
GO

CREATE TABLE tmp_xx_xx_testTable (u_id int, u_name varchar(10), u_add varchar(10))
GO

INSERT INTO dbo.tmp_xx_xx_testTable VALUES (6,'16','DDD'  )

INSERT INTO tmp_xx_xx_testTable (u_id,u_name,u_add) 
SELECT u_id,u_name,u_add FROM TestTable

drop TABLE TestTable
GO


EXECUTE sp_rename
                N'[dbo].[tmp_xx_xx_testTable]',
                N'TestTable';
GO

--SELECT * FROM testTable
--DROP TABLE testable
Run Code Online (Sandbox Code Playgroud)

没有分隔符失败的原因是,在脚本可以执行之前,它必须被编译,并且为了被编译,每个语句引用的所有对象在编译时都必须存在。然而,解析器遇到引用不存在对象的语句。对象应该由脚本中的先前语句创建,但是由于脚本尚未执行,因此它们也尚未创建。结果,丢失的对象无法编译脚本。

添加分隔符等同于在分隔符之间突出显示和执行脚本部分,除了由管理工具(SSMS 或 sqlcmd)自动完成之外,它会在发送脚本之前解释分隔符(或者,在这种情况下,它的部分)到服务器。