2016-11-28 37 views
3

我有一個腳本,我正在向表中添加一列,並在我用另一個表中的數據填充該列之後立即執行。我在我添加的列上收到'無效的列名'錯誤。事務中的SQL Server'無效的列名'

的錯誤,特別是Invalid column name 'tagID'.

BEGIN TRANSACTIONCOMMIT之間的代碼實際上是一個更大的腳本的摘錄,但這是相關的摘錄(我需要它的所有成功或簡單地回滾):

BEGIN TRY 
BEGIN TRANSACTION 
    ALTER TABLE [Items] ADD tagID [uniqueidentifier] NULL 

    MERGE INTO 
    Items AS target 
    USING 
    Tags AS t ON t.tag = target.tag 
    WHEN MATCHED THEN 
    UPDATE SET target.tagID = t.id; 
COMMIT 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
    ROLLBACK TRANSACTION 
END CATCH 
GO 
+0

你是否檢查過Items.tagID存在?您是否在同一批次中的上述代碼片段之前在腳本中添加了「Items.tagID」?因爲如果是這樣,合併語句的分析發生在創建列之前,並且在任何運行之前都會失敗。 –

+0

你可以自行執行'ALTER TABLE'命令嗎? – gmiley

+0

我認爲這會給你一些你的問題的信息。 http://stackoverflow.com/questions/7426199/problem-with-alter-then-update-in-try-catch-with-tran-using-transact-sql/7452280#7452280 – DVT

回答

2

SQL Server試圖編譯批處理中的所有語句。如果該表不存在該語句的編譯被延遲,但沒有延遲編譯缺少的列。

您可以使用

BEGIN TRY 
BEGIN TRANSACTION 
    ALTER TABLE [Items] ADD tagID [uniqueidentifier] NULL 
    EXEC(' 
    MERGE INTO 
    Items AS target 
    USING 
    Tags AS t ON t.tag = target.tag 
    WHEN MATCHED THEN 
    UPDATE SET target.tagID = t.id; 
') 
COMMIT 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
    ROLLBACK TRANSACTION 
END CATCH 
GO 

推柱的使用爲孩子批次創建後列編。它仍然屬於在父範圍中打開的同一事務。

1

事務範圍適用於DML操作,不​​適用於DDL操作。所以不知道爲什麼你在同一個事務塊中有ALTER語句。如果沒有錯,您應該在事務處理塊外部有該ALTER語句。

ALTER TABLE [Items] ADD tagID [uniqueidentifier] NULL 
BEGIN TRANSACTION 
    MERGE INTO 
    ..... 

另外,我想從你的ALTER語句中刪除從列的數據類型的[]

ALTER TABLE [Items] ADD tagID UniqueIdentifier; 
+0

我很困惑,根據http://stackoverflow.com/a/4736346/1670610,事務性DDL是SQL Server中的一件事情。您是否說我無法在同一事務中合併DML和DDL,或者DDL不能在SQL Server中進行事務? (請原諒我的無知,迄今爲止我只和MySQL一起工作過) – charmeleon

+0

@charmeleon,看起來像DDL命令也是'SQL Server'中的事務的一部分,但通常DML被封裝在反向塊中。 Sp是的,你可以在事務中擁有它......但是在你的情況下,檢查'ALTER'語句並嘗試在事務塊之外。可能會在一個單獨的反轉塊中 – Rahul