2009-06-26 121 views
0

在下面的情況下,Combine視圖中的最終選擇失敗,有什麼想法爲什麼?爲什麼sql select語句失敗?

子集表沒有對應於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服務器R2

+0

有點格式化會讓你更多的迴應。 – pugmarx 2009-06-26 21:54:43

回答

6

可能是因爲在某些行,M.Code包含字面單詞「三」,並認爲是試圖投非 - 將數字看成一個int(你可能會把「3」變成一個int,但不是「puppy」或「three」等)。

編輯:添加了評論,但值得在此處添加。 SQL Server將嘗試並儘可能高效地執行和加入,並且它會嘗試在加入之前顯式應用where子句。

如果您認爲現今的VIEW幾乎完全像真正的桌子一樣工作,這是有道理的。它必須做些與此相似的事情;否則,它會加入所有內容並在被濾除之前返回所有值。

非常昂貴。

我不確定的是如果執行計劃會顯示這個級別的細節。

2

您將字符串「three」插入MasterCodes.Code,並且您的視圖試圖將此值轉換爲整數。這個SQL應該給出相同的錯誤:

select cast("three" as int) 

解決方法?在您的插入語句中將「three」替換爲「3」。

+0

'三'值不應該由視圖首先選擇,子集表沒有ID = 3的行,並且內部連接到MasterCodes表。我的問題是,爲什麼系統在Combine視圖中無法返回時嘗試將「三」值轉換爲第一個整數。 – jsr 2009-06-26 21:54:58

+0

可能是因爲它在加入之前將您的WHERE子句應用於MasterCOdes(因此,投射所有行)。原則上,它應該更有效率,這就是SQL Server將要嘗試的。 曾經有一段時間,視圖僅僅是一些奇特的存儲過程,但事情發生了變化,它們確實是一個虛擬表。 – hythlodayr 2009-06-26 23:44:07

0

因爲當你嘗試在條件邏輯中使用IntCode時,視圖試圖將「three」作爲int來投射。

使用ISNUMERIC()有一個case語句如果結果集是精確到創建視圖

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

: 「SELECT * FROM結合其代碼= '2' - 返回1行 SELECT * FROM Combine WHERE Code ='3' - 0行返回 SELECT * FROM Combine WHERE IntCode = 2 - 失敗,錯誤消息isMsg 245,級別16,狀態1,行15轉換varchar值'3'爲數據時轉換失敗鍵入int「。

然後唯一一次失敗的情況是當你嘗試與IntCode字段進行比較時,它幾乎看起來像是在嘗試將非數字值放在「IntCode = 2」比較左側時失敗,因爲這是唯一需要在代碼字段中提取每個值的時間。

希望有幫助!