[英]SQL Server Execution Plan Ambiguity
問題-消息8114,級別16,狀態5,第1行將數據類型nvarchar轉換為數值時出錯。 下面是SQL Server中的查詢
SELECT FIELD_VALUE,
FREQUENCY_COUNT
FROM Table1 IFNV
INNER JOIN Table2 IFV
ON IFNV.FIELD_KEY = IFV.FIELD_KEY
INNER JOIN Table3 IFVSD
ON IFVSD.FUNCTION_KEY = IFNV.FUNCTION_KEY
WHERE IFVSD.PROFILE_RUN_KEY = 78
AND IFV.FIELD_NAME = 'EMPLOYEE_ID'
AND
CASE
WHEN IFV.IS_VIRTUAL = 0
THEN IFV.RECORD_NAME
ELSE IFNV.RULE_NAME
END = 'EMPLOYEES'
AND FIELD_VALUE IS NOT NULL
ORDER BY FREQUENCY_COUNT DESC,
CAST(FIELD_VALUE AS NUMERIC(6,0)) DESC;
當數據庫中不存在任何表時(即表和數據最近已添加到數據庫中),不會發生此問題。 僅當這些表中存在大量數據時,才會發生這種情況。 (當我們清除數據庫並重新創建所有內容時,不會出現此錯誤,但遺憾的是,我們無法每次都清除數據庫並重新創建)。 不知道為什么它不是第一次發生
經過進一步分析,我們發現在SQL Server中,它首先執行Casting操作,然后執行WHERE子句。
有什么方法可以在不清除數據庫的情況下克服此執行流程?
如果您使用的是SQL Server 2012或更高版本,請嘗試以下操作
SELECT FIELD_VALUE,
FREQUENCY_COUNT
FROM Table1 IFNV
INNER JOIN Table2 IFV
ON IFNV.FIELD_KEY = IFV.FIELD_KEY
INNER JOIN Table3 IFVSD
ON IFVSD.FUNCTION_KEY = IFNV.FUNCTION_KEY
WHERE IFVSD.PROFILE_RUN_KEY = 78
AND IFV.FIELD_NAME = 'EMPLOYEE_ID'
AND
CASE
WHEN IFV.IS_VIRTUAL = 0
THEN IFV.RECORD_NAME
ELSE IFNV.RULE_NAME
END = 'EMPLOYEES'
AND FIELD_VALUE IS NOT NULL
ORDER BY FREQUENCY_COUNT DESC,
TRY_CAST(FIELD_VALUE AS NUMERIC(6,0)) DESC;
如果您使用的SQL Server版本早於2012,請嘗試以下操作。
SELECT FIELD_VALUE,
FREQUENCY_COUNT
FROM Table1 IFNV
INNER JOIN Table2 IFV
ON IFNV.FIELD_KEY = IFV.FIELD_KEY
INNER JOIN Table3 IFVSD
ON IFVSD.FUNCTION_KEY = IFNV.FUNCTION_KEY
WHERE IFVSD.PROFILE_RUN_KEY = 78
AND IFV.FIELD_NAME = 'EMPLOYEE_ID'
AND
CASE
WHEN IFV.IS_VIRTUAL = 0
THEN IFV.RECORD_NAME
ELSE IFNV.RULE_NAME
END = 'EMPLOYEES'
AND FIELD_VALUE IS NOT NULL
ORDER BY FREQUENCY_COUNT DESC,
CASE WHEN FIELD_VALUE NOT LIKE '%[^0-9]%'
THEN CAST(FIELD_VALUE AS NUMERIC(6,0))
ELSE NULL
END DESC;
編輯
基本上,這意味着您正在嘗試將值轉換為大於numeric(6,0)的numeric(6,0)。 一個更簡單的選擇是在您的order by子句中使用LEFT(FIELD_VALUE,6)而不是CAST
SELECT FIELD_VALUE,
FREQUENCY_COUNT
FROM Table1 IFNV
INNER JOIN Table2 IFV
ON IFNV.FIELD_KEY = IFV.FIELD_KEY
INNER JOIN Table3 IFVSD
ON IFVSD.FUNCTION_KEY = IFNV.FUNCTION_KEY
WHERE IFVSD.PROFILE_RUN_KEY = 78
AND IFV.FIELD_NAME = 'EMPLOYEE_ID'
AND
CASE
WHEN IFV.IS_VIRTUAL = 0
THEN IFV.RECORD_NAME
ELSE IFNV.RULE_NAME
END = 'EMPLOYEES'
AND FIELD_VALUE IS NOT NULL
ORDER BY FREQUENCY_COUNT DESC,
LEFT(FIELD_VALUE , 6) DESC;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.