2017-05-03 70 views
-1

我想添加一列到表,然後插入數據到它,然後刪除該列。我希望這是一個交易。 爲了我的問題,我簡化了這裏的問題,實際上我正在使用新的列臨時從另一個表中獲取一些數據,然後將其插入到已更改的表中。我有與簡化版本相同的問題。SQL Server的 - ALTER TABLE和插入在同一事務

ALTER TABLE語句之後,我有需要GO,但SSMS告訴我

Msg 102, Level 15, State 1, Line 6 
Incorrect syntax near ';'. 

如果我刪除了GO,插入語句試圖插入到新添加的列時失敗。

Msg 207, Level 16, State 1, Line 8 
Invalid column name 'NewCol'. 

如果我運行BEGIN TRAN與正常工作的GOALTER TABLE聲明。但我需要這個在交易中。

任何幫助表示讚賞。代碼如下:

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 
+2

這有什麼用?爲什麼添加一個立即丟棄的列?這對我來說沒有意義。你試圖用這個解決的實際問題是什麼? –

+0

爲什麼不使用臨時表而不是像這樣添加和刪除列? –

回答

1

您可以使用臨時表/變量:

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 
+0

這是一個表變量,而不是臨時表。不同的動物,他們不能/不應該交替使用。 – alroc

1

您這裏有2個不同的問題。首先是批次的概念。 GO是SSMS(和其他工具)理解的「命令」;它用於將一串文本分成批次。批處理是應用程序(SSMS)提交給數據庫引擎執行的工作單元(代碼)。當引擎收到批處理時,它將首先編譯它。並且整個批次都是一次完成編譯。雖然批量在嘗試使用它之前添加了列,但編譯器在評估插入查詢時不會考慮您的alter語句。因此,你會得到錯誤。

不幸的是,您不能將您的腳本分成多個批次,因爲由於使用的邏輯,整個腳本必須在單個批次內運行。爲了解決這個問題,你可以對alter語句後面的所有語句使用動態sql語句。但這是一項高級技巧,我不能推薦它。說實話,這種做法似乎有缺陷;我認爲你應該重新評估導致你走上這條道路的決定。一個重要的考慮是純tsql中的錯誤處理很難並且不一致 - 即使對於經驗豐富的用戶也是如此。