簡體   English   中英

SQL Server執行計划的歧義

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM