T-SQL选择与ISNUMERIC匹配的值,并且也在指定范围内.(加上Linq-to-sql)

Tob*_*oby 4 t-sql linq-to-sql predicatebuilder

我试图从一个表中选择行(其中一个(NVARCHAR)列在数值范围内).

SELECT ID, Value
FROM Data
WHERE ISNUMERIC(Value) = 1 AND CONVERT(FLOAT, Value) < 66.6
Run Code Online (Sandbox Code Playgroud)

不幸的是,作为SQL规范的一部分,AND子句不必短路(并且不在MSSQL Server EE 2008上).更多信息:SQL WHERE子句的短路评估是什么?

我的下一次尝试是尝试这个,看看我是否可以延迟评估CONVERT

SELECT ID, Value
FROM Data
WHERE (CASE WHEN ISNUMERIC(Value) = 1 THEN CONVERT(FLOAT, Value) < 66.6 ELSE 0 END)
Run Code Online (Sandbox Code Playgroud)

但我似乎无法使用CONVERT的结果<(或任何比较).它因错误而失败

Incorrect syntax near '<'.
Run Code Online (Sandbox Code Playgroud)

我可以逃脱

SELECT ID, CONVERT(FLOAT, Value) AS Value
FROM Data
WHERE ISNUMERIC(Value) = 1
Run Code Online (Sandbox Code Playgroud)

所以显而易见的解决方案是将整个select语句包装在另一个SELECT和WHERE中,并从内部select和filter中返回转换后的值,在那里选择外部select.不幸的是,这是我的Linq-to-sql问题的来源.我不仅过滤了一个范围,而且过滤了很多,或者只是记录的存在(有一些日期范围选择和比较我遗漏了. )

基本上我希望能够生成这样的东西:

SELECT ID, TypeID, Value
FROM Data
WHERE (TypeID = 4 AND ISNUMERIC(Value) AND CONVERT(Float, Value) < 66.6) 
      OR (TypeID = 8 AND ISNUMERIC(Value) AND CONVERT(Float, Value) > 99)
      OR (TypeID = 9)
Run Code Online (Sandbox Code Playgroud)

(在每个选项中都有一些其他条款.)如果我在内部选择中过滤掉非ISNUMERIC值,这显然不起作用.

正如我所提到的,我正在使用Linq-to-sql(和PredicateBulider)来构建这些查询,但不幸的是

Datas.Where(x => ISNUMERIC(x.Value) ? Convert.ToDouble(x.Value) < 66.6 : false)
Run Code Online (Sandbox Code Playgroud)

获取转换为此失败的初始问题.

WHERE (ISNUMERIC([t0].[Value]) = 1) AND ((CONVERT(Float,[t0].[Value])) < @p0)
Run Code Online (Sandbox Code Playgroud)

我的最后一招必须是针对每个比较在同一桌面上的双重选择进行外连接,但这不是一个真正的想法解决方案.我想知道是否有人之前遇到过类似的问题?

Adr*_*der 8

我不认为问题是AND本身,而是从NVARCHAR到FLOAT的转换

看看下面的例子

DECLARE @Table TABLE(
        Value NVARCHAR(10)
)

INSERT INTO @Table SELECT '1'
INSERT INTO @Table SELECT '100'
INSERT INTO @Table SELECT 'A'

SELECT  *
FROM    @Table
WHERE   ISNUMERIC(Value)= 1 AND CAST(CAST(Value AS VARCHAR(10)) AS FLOAT) > 50

SELECT  *
FROM    @Table
WHERE   ISNUMERIC(Value)= 1 AND CAST(Value AS FLOAT) > 50
Run Code Online (Sandbox Code Playgroud)

最后一个选择是我得到错误说明的地方

消息8114,级别16,状态5,行13错误将数据类型nvarchar转换为浮点数.

但第一个选择工作正常.