为什么sql select语句失败?

时间:2009-06-26 21:44:51

标签: sql

在下面的场景中,Combine视图中的最终选择失败,为什么会有任何想法?

Subset表没有与MasterCodes中不会转换为整数值的行相对应的行。

CREATE TABLE MasterCodes (
  ID INT
, Code VARCHAR(10) )
GO

CREATE TABLE Subset (
  ID INT )
GO


CREATE VIEW Combine AS
SELECT S.ID
, M.Code
, CAST(M.Code AS INT) IntCode
FROM Subset S
INNER JOIN MasterCodes M ON M.ID = S.ID
GO

INSERT MasterCodes (ID, Code) VALUES (1, '1')
INSERT MasterCodes (ID, Code) VALUES (2, '2')
INSERT MasterCodes (ID, Code) VALUES (3, 'three')
INSERT MasterCodes (ID, Code) VALUES (4, '4')
INSERT Subset (ID) VALUES (1)
INSERT Subset (ID) VALUES (2)
INSERT Subset (ID) VALUES (4)


SELECT * FROM Combine -- 3 rows returned

SELECT * FROM Combine WHERE Code = '2' -- 1 row returned

SELECT * FROM Combine WHERE Code = '3' -- 0 rows returned

SELECT * FROM Combine WHERE IntCode = 2 -- fails, error msg is

Msg 245, Level 16, State 1, Line 15
Conversion failed when converting the varchar value 'three' to data type int.

环境是Sql2k5标准版(64位)ON Win2k3 Server R2

4 个答案:

答案 0 :(得分:6)

可能因为在某一行中,M.Code包含字面意思“三”,并且视图试图将非数字外观单词转换为int(你可以将“3”转换为int,但不能“小狗”或“三个”等。)。

编辑:添加了评论,但值得在此处添加。 SQL Server将尝试尽可能高效地执行和加入,并且尝试在加入之前显然应用where子句。

如果您认为VIEW现在几乎完全像真实表一样工作,那么这是有道理的。它必须与此类似;否则,它将加入所有内容并在过滤之前返回所有值。

非常昂贵。

我不确定的是执行计划是否会显示这种详细程度。

答案 1 :(得分:2)

您正在将字符串“three”插入MasterCodes.Code,并且您的视图正在尝试将此值强制转换为整数。这个SQL应该给出同样的错误:

select cast("three" as int)

解决方案?在插入语句中将“3”替换为“3”。

答案 2 :(得分:0)

因为当您尝试在条件逻辑中使用IntCode时,视图会尝试将“three”转换为int。

将isnumeric()与case语句一起使用以创建视图

case when isnumeric(field) then
    cast(field as int)
else
    null
end AS IntCode

答案 3 :(得分:0)

如果您的结果集准确无误: “SELECT * FROM Combine WHERE Code ='2' - 返回1行 SELECT * FROM组合WHERE Code ='3' - 返回0行 SELECT * FROM Combine WHERE IntCode = 2 - 失败,错误消息msMsg 245,Level 16,State 1,Line 15转换varchar值'three'到数据类型int时失败。“

那么它失败的唯一时间是当你尝试与IntCode字段进行比较时,当它试图将非数字值放在“IntCode = 2”比较的左侧时,它似乎失败了,因为这是唯一需要在代码字段中获取每个值的时间。

希望有所帮助!