我如何查询“之间”非数字字段上的数字数据?
我刚刚在数据库中发现了一个查询失败,导致报告失败。查询的基本要点:
Select *
From table
Where IsNull(myField, '') <> ''
And IsNumeric(myField) = 1
And Convert(int, myField) Between @StartRange And @EndRange
现在,myField 并不在所有行中包含数字数据[它是 nvarchar 类型]...但是这个查询显然是这样设计的:它只关心该字段中的数据所在的行数字。
问题在于,T-SQL(据我所知)不会短路Where子句,从而导致它放弃数据非数字的记录,但有例外:
Msg 245,Level 16,State 1、1号线 将 nvarchar 值“/A”转换为 int 数据类型时转换失败。
无法将 myField 为数字的所有行转储到临时表中,然后查询该字段在指定范围内的行,什么我可以做到这一点吗?
我的第一次解析纯粹是为了尝试分析返回的数据并查看发生了什么:
Select *
From (
Select *
From table
Where IsNull(myField, '') <> ''
And IsNumeric(myField) = 1
) t0
Where Convert(int, myField) Between @StartRange And @EndRange
但是我得到了与第一个查询相同的错误,我不确定我是否理解,因为我没有转换任何不应该转换的数据此时不是数字。子查询应该只返回 myField 包含数字数据的行。
也许我需要早茶,但这对任何人都有意义吗?另一双眼睛会有所帮助。
提前致谢
I've got a query that I've just found in the database that is failing causing a report to fall over. The basic gist of the query:
Select *
From table
Where IsNull(myField, '') <> ''
And IsNumeric(myField) = 1
And Convert(int, myField) Between @StartRange And @EndRange
Now, myField doesn't contain numeric data in all the rows [it is of nvarchar type]... but this query was obviously designed such that it only cares about rows where the data in this field is numeric.
The problem with this is that T-SQL (near as I understand) doesn't shortcircuit the Where clause thus causing it to ditch out on records where the data is not numeric with the exception:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the nvarchar value '/A' to data type int.
Short of dumping all the rows where myField is numeric into a temporary table and then querying that for rows where the field is in the specified range, what can I do that is optimal?
My first parse purely to attempt to analyse the returned data and see what was going on was:
Select *
From (
Select *
From table
Where IsNull(myField, '') <> ''
And IsNumeric(myField) = 1
) t0
Where Convert(int, myField) Between @StartRange And @EndRange
But I get the same error I did for the first query which I'm not sure I understand as I'm not converting any data that shouldn't be numeric at this point. The subquery should only have returned rows where myField contains numeric data.
Maybe I need my morning tea, but does this make sense to anyone? Another set of eyes would help.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用
CASE
语句。Use a
CASE
statement.IsNumeric 仅告诉您该字符串可以转换为 SQL Server 中的数字类型之一。它可能能够将其转换为货币或浮点数,但可能无法将其转换为整数。
将您的更改
为:(
也就是说,您希望 myField 仅包含数字,并适合 int)
编辑 示例:
结果:
IsNumeric only tells you that the string can be converted to one of the numeric types in SQL Server. It may be able to convert it to money, or to a float, but may not be able to convert it to an int.
Change your
to be:
(that is, you want myField to contain only digits, and fit in an int)
Edit examples:
result:
您必须强制 SQL 按特定顺序计算表达式。
这是一个解决方案
和另一个
SQL 是声明性的:你告诉优化器你想要什么,而不是如何去做。上述技巧迫使事情按照一定的顺序完成。
You'd have to force SQL to evaluate the expressions in a certain order.
Here is one solution
and another
SQL is declarative: you tell the optimiser what you want, not how to do it. The tricks above force things to be done in a certain order.
不确定这是否对您有帮助,但我确实在某处读到,使用 CONVERT 进行不正确的转换总是会在 SQL 中生成错误。所以我认为最好在 where 子句中使用 CASE 以避免 CONVERT 在所有行上运行
Not sure if this helps you, but I did read somewhere that incorrect conversion using CONVERT will always generate error in SQL. So I think it would be better to use CASE in where clause to avoid having CONVERT to run on all rows