我有一張桌子,我們就叫它吧A。我想從該表中洗掉 ID 為 1 和 2 的行。為此,我創建了一個表變數@B,其中包含值 1 和 2,但我將命名該列PK。
現在我這樣做:
DELETE FROM A
WHERE ID IN (
SELECT ID
FROM @B
)
注意我的(故意的)編程錯誤。在子選擇中,我使用了錯誤的列名。意外的是,它與表 A 中使用的名稱相同。
這應該會導致“無效的列名”錯誤,對吧?除非它沒有。它執行。不僅如此,表 A 中的所有資料都會被洗掉。好像沒有更多的謂詞。
我創建了一個完整的演示腳本:
-- What happened to my data???
IF OBJECT_ID('tempdb..#JustATable') IS NOT NULL
DROP TABLE #JustATable
CREATE TABLE #JustATable (
PK INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
ID INT NOT NULL,
NOTE VARCHAR(100) NOT NULL
)
INSERT INTO #JustATable (ID, NOTE)
SELECT database_id, DB_NAME(database_id)
FROM sys.databases;
SELECT NULL [inserted all the rows from sys.databases into the temptable], *
FROM #JustATable;
DECLARE @JustATableVariable TABLE (
PK INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
ID_2 INT NOT NULL,
NOTE VARCHAR(100) NOT NULL
)
INSERT INTO @JustATableVariable (ID_2, NOTE)
SELECT database_id, DB_NAME(database_id)
FROM sys.databases
WHERE database_id = 2;
SELECT NULL [this is my table variable data], *
FROM @JustATableVariable;
DELETE FROM #JustATable
WHERE ID IN (
SELECT ID_2
FROM @JustATableVariable
);
SELECT NULL [I have just removed tempdb from the temptable], *
FROM #JustATable;
DELETE FROM #JustATable
WHERE ID IN (
SELECT ID /* this is the wrong column name but the same name as used in the temptable column */
FROM @JustATableVariable
);
SELECT NULL [wait...where is my data?], *
FROM #JustATable;
有人可以向我解釋這里發生了什么嗎?有沒有人見過這種行為?這可能是一個錯誤嗎?
uj5u.com熱心網友回復:
在子查詢中:
... (select id from @b)
...該列id不完全合格。因此根據 SQL 規范,RDBMS 將首先查看 id 列是否存在于 table 中@b。如果沒有,它將“向上”搜索,直到在 table 中找到 id 列a。該查詢實際上等同于:
delete from a where id in (select a.id from @b)
語法正確,語意錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/439772.html
上一篇:洗掉和附加作品,但不替換html
