use*_*574 1 t-sql sql-server sql-server-2012
我有一个非常简单的代码正在尝试运行,但是由于我不明白的原因,它无法正常工作。这是我的代码:
WITH CTE AS
(
SELECT DISTINCT OrderNo
FROM OrderDet
WHERE PartNo LIKE '%.%'
AND OrderNo NOT LIKE '%[a-z]%'
)
SELECT *
FROM CTE
WHERE CAST(CTE.OrderNo AS INT) >= 21187
Run Code Online (Sandbox Code Playgroud)
运行此代码将引发以下错误:
将varchar值'20361E'转换为数据类型int时,转换失败。
现在我知道有些OrderNo值包含“ E”,但是就我而言,我正在CTE中将其过滤掉。如果我自己在CTE中运行该语句,则会得到580条记录,而这些记录中都没有字母。
这里发生了什么?
如评论中所述,您无法真正控制是否CAST在过滤器之前尝试;这完全取决于SQL Server选择如何优化查询。
另外,检查是否存在小数和无az并不是过滤非数字的可靠方法。
我认为,以下两种方法都消除了CTE的需要,因为您只是在使用它来尝试强制执行过滤器。CTE可以合并到其余查询中。也许值得一读的是关于CTE的其他一些花絮。
试试TRY_CONVERT()(我在这里写过):
WHERE TRY_CONVERT(int, CTE.OrderNo) >= 21187;
Run Code Online (Sandbox Code Playgroud)
如果您使用的旧版本不支持TRY_CONVERT,则可以尝试CASE(也许是另一本有用的读物):
WHERE CASE WHEN ISNUMERIC(CTE.OrderNo) = 1 THEN CTE.OrderNo END >= 21187;
Run Code Online (Sandbox Code Playgroud)
自从我们知道版本以来,您的查询可以简化为:
SELECT DISTINCT OrderNo
FROM dbo.OrderDet
WHERE PartNo LIKE '%.%'
AND TRY_CONVERT(int, OrderNo) >= 21187;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
64 次 |
| 最近记录: |