我正在尝试向表中添加一列,然后将数据插入其中,然后删除该列。我希望这是一个交易。 出于我的问题的目的,我在这里简化了问题,实际上我暂时使用新列从另一个表中获取一些数据,然后将其插入到更改的表中。我对简化版本有同样的问题。
ALTER TABLE
语句之后,我需要GO
,但SSMS告诉我
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near ';'.
如果删除GO
,则在尝试插入新添加的列时,insert语句将失败。
Msg 207, Level 16, State 1, Line 8
Invalid column name 'NewCol'.
如果我使用ALTER TABLE
在BEGIN TRAN
之前运行GO
语句,则可以正常运行。但我需要这是一个交易。
感谢任何帮助。代码如下:
BEGIN TRY
BEGIN TRAN
ALTER TABLE myTable
ADD NewCol varchar(6);
GO
INSERT INTO myTable (NewCol, BillingName, BillingAddress)
SELECT * FROM OPENQUERY(linkedServer, 'SELECT * FROM customer');
ALTER TABLE myTable
DROP COLUMN NewCol;
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
答案 0 :(得分:2)
您可以使用表变量:
BEGIN TRY
BEGIN TRAN
DECLARE @temp TABLE(NewCol <type>, BillingName <type>, BillingAddress <type>);
INSERT INTO @temp (NewCol, BillingName, BillingAddress)
SELECT * FROM OPENQUERY(linkedServer, 'SELECT * FROM customer');
INSERT INTO myTable
SELECT BillingName, BillingAddress FROM @temp;
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
答案 1 :(得分:1)
这里有两个不同的问题。首先是批次的概念。 GO是一个&#34;命令&#34; SSMS(以及其他一些工具)理解这一点;它用于将一串文本分成批次。批处理是应用程序(SSMS)提交给数据库引擎执行的工作单元(代码)。当引擎收到批处理时,它将首先编译它。并且一次完成整个批次的编译。尽管您的批处理在尝试使用该列之前添加了该列,但编译器在评估插入查询时不会考虑您的alter语句。因此,你得到错误。
不幸的是,您无法将脚本分成多个批次,因为由于使用了逻辑,整个脚本必须在一个批处理中运行。为了解决这个问题,您可以对alter语句后面的所有语句使用动态sql。但这是一项高级技能,我无法推荐它。说实话,这种方法似乎有缺陷;我认为你应该重新评估导致你走这条道路的决定。一个重要的考虑因素是纯tsql中的错误处理是困难和不一致的 - 即使对于有经验的人来说也是如此。