在哪個方向檢查 SQL Server WHERE 子句條件?
我有這個查詢:
SELECT RCodeID as 'ListItemID', RCode as 'ListItemName' FROM RCode WHERE RCode not like '%,%' AND ISNUMERIC(RCode) = 1 AND CAST(RCode as int) >= CAST(@From as int) AND CAST(RCode as int) <= CAST(@To as int) ORDER BY ListItemName;
那麼 SQL Server 以什麼順序(從右到左/從左到右)檢查這些條件?
因為我得到了那些也有
,
逗號的行,但我想在ISNUMERIC(Rcode)
執行之前排除它們。表中數據:
+---------+--------+ | RCodeID | RCode | +---------+--------+ | 1 | 342 | +---------+--------+ | 2 | 232,23 | +---------+--------+ | 3 | 323xs | +---------+--------+
輸入:
@From
=300 和@To
=400預期輸出:
+---------+--------+ | RCodeID | RCode | +---------+--------+ | 1 | 342 | +---------+--------+
更新
RCode not like '%,%' AND ISNUMERIC(RCode) = 1
我在視圖中移動了程式碼。視圖顯示正確的數據。但是當我在上面的查詢中使用該視圖時,逗號分隔值的轉換錯誤即將到來。如果視圖正在過濾該數據,那麼為什麼這些行會出現?
WHERE
子句中沒有執行順序之類的東西。您正在像大多數開發語言(Java、C++、VB、JavaScript)一樣在命令式和過程式範式中思考。SQL(幾乎)是函式式的並且是基於集合的。如果在任何實際術語中存在執行順序,它就會被隱藏在引擎黑匣子中。
甚至沒有加入訂單。當引擎看起來更好並且相信當我說引擎正在執行大量性能檢查、統計、啟發式時,事情就完成了。
如果事情沒有像您預期的那樣發生,那麼某個地方就會出現錯誤。
只是猜測,但逗號可能是您的數字數據的十進製表示。
編輯
我明白了,您收到如下錯誤:
消息 245,級別 16,狀態 1,行 19 將 varchar 值“232,23”轉換為數據類型 int 時轉換失敗。
即使您將用於刪除不需要的行的部分放入子查詢中,您也會收到錯誤消息(同樣,因為引擎以這種方式執行操作並對其進行排序似乎是最優化的)。
完成它的一種方法是刪除所有不需要的行並將其放在另一個表上。如果您願意,您可以使用#temporary 表,它是一個巨大的表,但對於商場範例,我使用了一個最動態的表變數。
create table RCode ( RCodeID int not null ,RCode varchar(10) not null ) GO insert into dbo.RCode (RCodeID, RCode) values (1,'342') ,(2,'232,23') ,(3,'323xs') GO declare @from int = 300, @to int = 400 declare @temp as table ( [ListItemID] int not null ,[ListItemName] varchar(10) not null ) insert into @temp SELECT RCodeID as [ListItemID], RCode as [ListItemName] FROM RCode WHERE RCode not like '%,%' AND ISNUMERIC(RCode) = 1 select [ListItemID], [ListItemName] from @temp as x WHERE CAST(x.[ListItemName] as int) >= CAST(@From as int) AND CAST(x.[ListItemName] as int) <= CAST(@To as int) ORDER BY x.[ListItemName];
非物化視圖無濟於事
正如 OP 評論的那樣,使用視圖不起作用。它等同於使用下面的子查詢。
select [ListItemID], [ListItemName] from ( SELECT RCodeID as [ListItemID], RCode as [ListItemName] FROM RCode WHERE RCode not like '%,%' AND ISNUMERIC(RCode) = 1 ) as x WHERE CAST(x.[ListItemName] as int) >= CAST(@From as int) AND CAST(x.[ListItemName] as int) <= CAST(@To as int) ORDER BY x.[ListItemName];
OP 將得到相同的錯誤,因為視圖只是查詢的別名,除非它是具體化的。這意味著引擎只會將其評估為像上面這樣的子查詢,並將評估為像 OP 第一個範例這樣的簡單查詢。換句話說,引擎將看到它在語義上是相同的查詢,並將以相同的方式執行它。
注意正確性
您的查詢不會顯示值為 的行
350,5
。這是正確的嗎?根據您的語言設置,記住0,5
可以是一半(是的,它交換逗號和點)。因此,請確保擺脫逗號並使用整數是您想要的。