为什么我得到"将数据类型nvarchar转换为float时出错。"在我的Sql?

时间:2015-07-18 17:35:42

标签: sql-server type-conversion

请注意http://sqlfiddle.com/#!3/6f14c/7

这是架构:

CREATE TABLE tmp1 (
  ts DATETIME NOT NULL,
  message NVARCHAR(128) NOT NULL
)
INSERT INTO tmp1 (ts,message) VALUES
('2015-06-24 00:28:18', '121a'),
('2015-06-24 00:30:18', '28.315b')

这是SQL语句:

;with data as (
    select ts,CONVERT(FLOAT, replace(message,'a','')) seconds from tmp1
    where message LIKE '%a'
)
select * from data where seconds > 100

运行它会产生将数据类型nvarchar转换为float的错误。

为什么?

2 个答案:

答案 0 :(得分:2)

SQL Server不保证表达式的评估顺序。发生的事情是转换是在过滤之前发生的,因为它被推送到读取数据的进程部分。

CTE和子查询不会影响此优化。在单个查询中,在早期版本的SQL中绕过它的唯一方法是使用case

select ts,
       (case when isnumeric(replace(message, 'a', '')) = 1
             then CONVERT(FLOAT, replace(message,'a',''))
        end)
from tmp1
where message LIKE '%a' and seconds > 100;

在SQL Server 2012+中,您可以改为使用try_convert()

with data as (
    select ts, try_convert(FLOAT, replace(message,'a','')) as seconds
    from tmp1
    where message LIKE '%a'
)
select * from data where seconds > 100

答案 1 :(得分:0)

戈登的回答实际上是正确的!或者,我认为您也可以在SQL Server中使用trim函数来执行此操作:

;WITH data
AS (
    SELECT ts
        ,CONVERT(FLOAT, ltrim(rtrim(replace(message, 'a', '')))) seconds
    FROM tmp1
    WHERE message LIKE '%a'
    )
SELECT *
FROM data
WHERE seconds > 100

SQL Fiddle Demo