2009-08-06 139 views
5

我目前有一個表,其列爲varchar。此欄可以保存數字或文字。在某些查詢我把它當作一個bigint轉換數據類型時出錯varchar

只要有唯一編號,在此領域沒有任何麻煩,但一分鐘甚至一列(它在別的表是bigint列之間我做一個連接)有這個字段中的文本和數字我得到了一個「錯誤轉換數據類型varcharbigint」。錯誤,即使在WHERE部分我確保沒有任何文本字段出現。

爲了解決這個問題,我創建一個視圖如下:

SELECT  TOP (100) PERCENT ID, CAST(MyCol AS bigint) AS MyCol 
FROM   MyTable 
WHERE  (isnumeric(MyCol) = 1) 

但即使視圖只顯示與數值的行蒙上Mycol爲bigint我還得到一個錯誤轉換數據類型爲varchar爲bigint運行下面的查詢時:

SELECT * FROM MyView where mycol=1 

對視圖做查詢時它不應該知道是怎麼回事就可以了後面!它應該只是看到兩個bigint領域! (see attached image,即使mssql管理工作室顯示視圖字段爲bigint)

+1

我個人認爲你正在解決錯誤的問題。如果您爲了兩個不同的目的而使用一列,那麼您的架構/數據庫設計會出現問題。 – 2009-08-06 11:13:13

+1

是的,我知道,但整個系統現在已經太重要了 – adinas 2009-08-06 13:24:44

回答

0

您是否嘗試將其他表的bigint字段轉換爲varchar?對我來說,執行更強大的轉換是有意義的...如果varchar字段被索引,它不應該太多地影響你的性能。

+0

這可能是一個解決方案,但真正讓我感興趣的是在視圖上獲取錯誤,即使它只有bigint字段 – adinas 2009-08-06 09:23:17

0

考慮創建一個多餘的bigint字段來保存af MyCol的整數值。

然後,您可以對新字段編制索引以加快加入速度。

+0

這意味着更改我的項目的大部分,每次選擇正確的領域... – adinas 2009-08-06 09:32:21

0

嘗試在2個階段做選擇。

首先創建一個視圖,用於選擇列號爲數字的所有列。

然後在該視圖中進行select varchar字段的選擇。

你可以看看的另一件事是你的表格設計,以消除對演員的需求。

編輯

  • 是一些數字比BIGINT大?
  • 有沒有空格,領先,尾隨或數字?
  • 是否有任何格式字符?小數點?
+0

試過。即使在查詢第二個視圖時,我仍然會得到相同的錯誤 – adinas 2009-08-06 09:31:08

1

理想情況下,您希望儘量避免以這種形式存儲數據 - 將BIGINT數據分割爲單獨的列以提高性能和查詢的便利性。

但是,您可以像本示例一樣進行JOIN。請注意,我是未使用ISNUMERIC()來確定它是否是有效的BIGINT,因爲它會驗證會導致轉換錯誤的錯誤值(例如十進制數)。

DECLARE @MyTable TABLE (MyCol VARCHAR(20)) 
DECLARE @OtherTable TABLE (Id BIGINT) 

INSERT @MyTable VALUES ('1') 
INSERT @MyTable VALUES ('Text') 
INSERT @MyTable VALUES ('1 and some text') 
INSERT @MyTable VALUES ('1.34') 
INSERT @MyTable VALUES ('2') 
INSERT @OtherTable VALUES (1) 
INSERT @OtherTable VALUES (2) 
INSERT @OtherTable VALUES (3) 

SELECT * 
FROM @MyTable m 
    JOIN @OtherTable o ON CAST(m.MyCol AS BIGINT) = o.Id 
WHERE m.MyCol NOT LIKE '%[^0-9]%' 

更新: 我可以找得到它,從而提供具有特定整數值的WHERE子句的工作沒有做對所謂BIGINT列另一個CAST()在WHERE子句中過的唯一途徑,是使用用戶定義的函數:

CREATE FUNCTION [dbo].[fnBigIntRecordsOnly]() 
RETURNS @Results TABLE (BigIntCol BIGINT) 
AS 
BEGIN 
INSERT @Results 
SELECT CAST(MyCol AS BIGINT) 
FROM MyTable 
WHERE MyCol NOT LIKE '%[^0-9]%' 
RETURN 
END 

SELECT * FROM [dbo].[fnBigIntRecordsOnly]() WHERE BigIntCol = 1 

我真的不認爲這是一個好主意性能明智的,但它是一個解決方案

0

嘗試使用這樣的:

SELECT 
    ID, 
    CAST(MyCol AS bigint) as MyCol 
FROM 
(
    SELECT TOP (100) PERCENT 
     ID, 
     MyCol 
    FROM 
     MyTable 
    WHERE 
     (isnumeric(MyCol) = 1) 
) as tmp 

這應該工作,因爲內部只選擇返回數值,外部選擇因此可以將第一個選擇的所有值轉換爲數字。看起來,在你自己的代碼中,SQL試圖在執行isnumeric函數之前進行強制轉換(也許它與優化有關)。

+0

您的查詢確實只返回包含數字的行。但是當它變成一個視圖和查詢視圖我得到相同的'錯誤轉換數據類型varchar到bigint'(只有當做「mycol = 1時我得到錯誤) – adinas 2009-08-06 09:55:50

1

要回答有關錯誤消息的問題:當您在另一個查詢中引用視圖名稱時(假設它是傳統視圖而非實例化視圖),SQL Server會有效地將視圖定義的宏替換爲消費查詢,然後執行。

這樣做的好處是,查詢優化器如果能看到整個查詢,可以做得更好,而不是單獨將視圖優化爲「黑盒子」。

結果是,如果發生錯誤,錯誤描述可能會令人困惑,因爲執行引擎正在訪問數據的基礎表,而不是視圖。

我不知道物化視圖是如何處理的,但我會想象它們被視爲像表一樣,因爲視圖數據被緩存在數據庫中。

話雖如此,我同意以前的答案 - 您應該重新考慮您的表格設計,並將文本和整數數據值分隔爲單獨的列。

1

試着改變你的看法,以這樣的:

SELECT TOP 100 PERCENT ID, 
Cast(Case When IsNumeric(MyCol) = 1 Then MyCol Else null End AS bigint) AS MyCol 
FROM MyTable 
WHERE (IsNumeric(MyCol) = 1) 
+0

對不起,這個查詢返回相同的'錯誤轉換數據類型varchar to bigint'err – adinas 2009-08-10 12:55:45

+0

您使用的是哪個版本的SQL Server?我已經在SQL2000中試過了,沒有任何問題。 很高興你找到了解決方案,無論如何:) – MartW 2009-08-10 15:57:41

2

確定。我終於創建了一個可行的觀點:

SELECT TOP (100) PERCENT id, CAST(CASE WHEN IsNumeric(MyCol) = 1 THEN MyCol ELSE NULL END AS bigint) AS MyCol 
FROM   dbo.MyTable 
WHERE  (MyCol NOT LIKE '%[^0-9]%') 

由於AdaTheDevCodeByMoonlight。我用你的兩個答案來解決這個問題。 (當然也要感謝其他的replier)

現在,當我與其他bigint cols連接或者執行像'SELECT * FROM MyView where mycol = 1'之類的操作時,它將返回正確的結果而不會出錯。我的猜測是,在查詢本身的CAST導致查詢優化器不看原始表基督教海特說的可能發生的事情與其他視圖

相關問題