查询评估路径

时间:2016-02-25 10:21:41

标签: sql-server sql-server-2014

更新:如果两个查询的顺序错误。第一个起作用,第二个起作用。

我遇到了一些令我难过的奇怪的SQL Server行为,我希望有人可以帮我弄清楚会发生什么。

我的查询需要从许多表中提取数据,包括products表。我们使用的模式非常严格,最近我们添加了一些新产品,这些产品在其名称中包含“重复”值(即我们每3,6或12个月向客户收费,而且该数字仅在文本中提供,在产品名称中。这咬人,但就是这样。)

我添加了WHERE子句来过滤掉3个特定产品,然后运行以下代码来获取数量重现因子:

CAST(RTRIM(SUBSTRING(e.NAME, CHARINDEX('-', e.NAME) +2 , 2)) as int)

没有什么过于花哨的,而WHERE条款专门过滤那3个产品,我们应该是好的。然后,我将检索到的值转换为一个整数,用于计算。

但是,看似随机,查询会抱怨两个字母组合无法转换为int值。

我的假设是,通过使用WHERE子句删除不需要的产品,其他产品永远不会被评估为开头。如果上面的代码是查询中的唯一内容,则运行查询。如果我们将e.NAME添加为唯一的其他字段,则会收到错误消息:

Conversion failed when converting the nvarchar value 'ni' to data type int.

我试图通过将产品硬编码到JOIN中来过滤掉不需要的产品(这应该不重要),但它没有帮助。

桌面上的执行计划和更新统计数据并未显示任何有价值的信息。

这会引发错误:

SELECT
    CAST(RTRIM(SUBSTRING(e.NAME, CHARINDEX('-', e.NAME) +2 , 2)) AS int) AS BillingFrequency
FROM 
    orders a
        JOIN order_items b ON a.ORDER_ID = b.ORDER_ID
        JOIN order_item_options c ON b.ORDER_ITEM_ID = c.ORDER_ITEM_ID
        JOIN prices d ON c.PRICE_ID = d.PRICE_ID AND d.TO_OPTION_ID IN (189, 190, 191)
        JOIN product_options_vw e ON d.TO_OPTION_ID = e.OPTION_ID AND e.OPTION_ID IN (189, 190, 191)
WHERE
    e.OPTION_ID IN (189, 190, 191)

这有效:

SELECT
     e.NAME
    , CAST(RTRIM(SUBSTRING(e.NAME, CHARINDEX('-', e.NAME) +2 , 2)) AS int) AS BillingFrequency
FROM 
    orders a
        JOIN order_items b ON a.ORDER_ID = b.ORDER_ID
        JOIN order_item_options c ON b.ORDER_ITEM_ID = c.ORDER_ITEM_ID
        JOIN prices d ON c.PRICE_ID = d.PRICE_ID AND d.TO_OPTION_ID IN (189, 190, 191)
        JOIN product_options_vw e ON d.TO_OPTION_ID = e.OPTION_ID AND e.OPTION_ID IN (189, 190, 191)
WHERE
    e.OPTION_ID IN (189, 190, 191)

1 个答案:

答案 0 :(得分:2)

我看到两个查询都是相同的,除了在第二个查询中再添加一个列,并且奇怪的是第二个查询对你起作用,不应该是。我建议使用try cast并尝试以下步骤

如果转换失败并且您可以看到

,请尝试将throw抛出null
Try_CAST(RTRIM(SUBSTRING(e.NAME, CHARINDEX('-', e.NAME) +2 , 2)) AS int)

您可以看到所有带有null的列,这可能会导致问题。另外的错误消息清楚地说明了..

  

转换nvarchar值时转换失败' ni'数据类型int。

所以你可以尝试只使用下面的部分,看看哪一个给你一个ni的输出

  

RTRIM(SUBSTRING(e.NAME,CHARINDEX(' - ',e.NAME)+2,2))