Sql-Server

在哪個方向檢查 SQL Server WHERE 子句條件?

  • July 28, 2018

我有這個查詢:

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可以是一半(是的,它交換逗號和點)。因此,請確保擺脫逗號並使用整數是您想要的。

引用自:https://dba.stackexchange.com/questions/212757