2011-09-09 167 views
3

我面臨一些奇怪的問題,並希望瞭解背後的原因。SQL Server |字符串比較

我們有兩個數據庫服務器假設A和B在這兩個這些服務器,我們有我們的應用程序的數據庫(相同的模式,但不同的記錄)

問題: 我們有一個類SqlQuery

Select * from Person where memberId=123456 

這查詢完美運行並返回在服務器上選擇的行 - 答: 但在不同的服務器-B上的相同查詢不返回任何記錄。

但是,如果我修改我的查詢

Select * from Person where memberId='123456' 

(注意單引號)

現在,我返回正確的記錄。

memberId的DataType是nchar(100)。從技術上講,我明白我應該使用單引號進行比較。

但只是想明白爲什麼會發生這種情況?

更新: 1)兩者具有完全相同的模式。 2)兩者都相同的記錄

實際代碼:

實際上這個查詢是一個動態創建,然後使用

declare @sql varchar(2000) 
    set @sql = 'SELECT * FROM PersonTrivia where memberId='+ @MemberId 
    print @sql 
    exec (@sql) 

執行,但此參數@MemberId爲varchar(250)

+2

對不起,可能看起來像一個明顯的問題,你再次檢查兩個表的模式是否相同? – GrandMasterFlush

+5

有趣的問題,但爲什麼你使用固定寬度的200字節列'nchar(100)'來存儲一個int? –

+0

哪些SQL Server版本是這些(哪個是哪個)?另外,字段memberId的排序順序是否相同? –

回答

2

查詢是否返回記錄或是否給出錯誤?

它看起來像你可以輸入數字到一個nchar字段,但是,你第一次添加一個字符,你將無法查詢「整數」了......或者至少看起來如此。

CREATE TABLE [dbo].[testnchar](
    [id] [nchar](10) NULL, 
    [name] [nchar](100) NULL 
) 
GO 

insert testnchar 
select 1, 222222 

select * from testnchar 
where name = 222222 

id   name 
--------- -------- 
1   222222 

insert testnchar 
select 1, 'test' 

select * from testnchar 
where name = 222222 

--Msg 245, Level 16, State 1, Line 1 
--Conversion failed when converting the nvarchar value 'test  

delete testnchar 
where name = 'test' 

select * from testnchar 
where name = 222222 

id   name 
--------- -------- 
1   222222 
+0

OP的確切含義是它們只是沒有結果而不是錯誤。這將是非常重要的一點信息! –

+0

它不返回任何記錄,沒有錯誤/異常 – Gaurav

0

顯然memberId轉換比較之前,INT(我假設有在2號機上查詢EXEC沒有錯誤?)。所以我的第一個猜測是,這是Sql Server文化特定的機器,即memberId可以在第一臺機器上轉換爲int,而不能在其他機器上轉換爲int。或者,由於記錄不同(?),第二臺機器上只有一些「錯誤」的記錄。但最後一件事情應該會導致運行時錯誤。

+0

Petr-不確定SQL服務器的文化具體的事情,導致這兩個服務器都由我們的託管服務提供商 – Gaurav

2

我會很感興趣知道你是否想出了爲什麼會發生這種情況的另一個原因,但我開始懷疑它。我相當肯定你在捕捉或壓制某處的錯誤。

考慮以下幾點:

CREATE TABLE [Person] 
(
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [MemberID] [nchar](200) NULL, 
    [Data] [varchar](50) NULL, 
    CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
    (
     [ID] ASC 
    ) 
) 

INSERT Person([MemberID],[Data]) VALUES ('1111111111', 'Test1'); 
INSERT Person([MemberID],[Data]) VALUES ('2222222222', 'Test2'); 
INSERT Person([MemberID],[Data]) VALUES ('3333333333', 'Test3'); 
INSERT Person([MemberID],[Data]) VALUES ('NON-NUMERIC', 'Test4'); 

SELECT * FROM Person WHERE MemberID = 2222222222 

上面的查詢將返回(1)導致AND錯誤。所以,如果你的代碼看起來像下面這樣:

command = new SqlCommand( 
    @"SELECT * FROM Person WHERE MemberID = 2222222222", connection); 
try 
{ 
    reader = command.ExecuteReader(); 
    while (reader.Read()) 
    { 
     Console.WriteLine("MemberID = " + reader["MemberID"]); 
    } 
    // We'll never get here. 
    reader.Close(); 
} 
catch { } 

,你會得到的結果將是MemberID = 2222222222。如果您正在使用SQL TRY...CATCH塊,也會發生這種情況。然而,如果我們改變訂單的記錄:

TRUNCATE TABLE [Person] 

INSERT Person([MemberID],[Data]) VALUES ('NON-NUMERIC', 'Test1'); 
INSERT Person([MemberID],[Data]) VALUES ('1111111111', 'Test2'); 
INSERT Person([MemberID],[Data]) VALUES ('2222222222', 'Test3'); 
INSERT Person([MemberID],[Data]) VALUES ('3333333333', 'Test4'); 

你實際上將得到(0)異常結果前拋出。最後,如果您將您的查詢更改爲:

SELECT T.* FROM 
(
    SELECT TOP 100 * 
    FROM Person 
    ORDER BY MemberID 
) T 
WHERE T.MemberID = 2222222222 

...您將得到(1)記錄和錯誤。

我的建議是找出是否以及爲什麼要抑制錯誤。我的總體建議是不將字符字段與整數進行比較,並依賴於隱式轉換。

1.羣集索引不要保證行的順序。它幾乎肯定會在這個測試中,但值得指出。

+0

我看不到任何方式,文字'123456'可能會導致所描述的行爲。希望如果OP顯示他們實際使用的價值將變得更清晰。 –

+0

我的猜測是由123456或任何值引起的隱式轉換爲int導致錯誤。 OP說SQL是在一個存儲過程中的,我猜測它是從正在處理錯誤的代碼中調用的。當你讓他做'CAST(memberId AS INT)'測試時,他可能是從查詢窗口做出來的,而不是在問題存儲過程中。 –