我最近設法使用這樣的查詢來鎖定我們的 SQL Server 資料庫(為了清晰起見,我進行了簡化):
SELECT *, NULL AS extraColmn
INTO #tempTable
FROM sourceTable
IF @@ROWCOUNT > 0
BEGIN
BEGIN TRANSACTION;
DELETE FROM sourceTable
INSERT INTO sourceTable
SELECT * FROM #tempTable;
COMMIT TRANSACTION;
DROP TABLE #tempTable
END
這有兩個明顯的問題。首先,INSERT/SELECT 陳述句應該明確列出列。其次,在執行 INSERT 時,源表和目標表的列數不同。正如預期的那樣,這導致了一個錯誤:
訊息 213,級別 16,狀態 1,第 1 行
列名或提供的值數量與表定義不匹配。
并且查詢在我們的生產服務器上失敗了。
但奇怪的是,當我在 SQL Server Management Studio 中運行相同的查詢時,它給出了該錯誤,但隨后鎖定了整個資料庫,以至于我不得不重新啟動資料庫服務器。
為什么?是交易嗎?我是這些方面的新手,但我明白如果在事務中遇到錯誤,它只會回滾——這就是重點。(請注意,該站點上大量使用 sourceTable,因此在運行時可能會有一些并發嘗試訪問它。)
為什么這只發生在 SQL Server Management Studio 中?
uj5u.com熱心網友回復:
IIRC,SSMS 中的默認設定意味著錯誤將導致批次的其余部分(直到下一個 GO 或命令結束)被跳過。因此,交易仍將打開并系結到您的 SSMS 視窗的會話。因此,如果您既不關閉會話視窗,也不顯式回滾該視窗中的事務,它將保持打開狀態,直到您這樣做(或重新啟動服務器)。
這就是我假設發生在你身上的事情。簡單的修復方法通常是斷開或關閉引發錯誤的 SSMS 會話視窗。或者,您可以在該會話中手動執行 ROLLBACK 命令,這樣您就不會丟失視窗或必須重新連接。
收到此錯誤的客戶端程式通常最終會關閉連接(通過錯誤處理或因為它崩潰),從而結束會話及其事務。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/361940.html
標籤:sql-server 查询语句
下一篇:TSQL-檢查是否存在
