2011-09-09 9 views
3

私はいくつかの奇妙な問題に直面しており、この背後にある理由を理解したい。我々は2台のデータベース・サーバーを持つSQL Server |文字列の比較

は、我々のアプリケーションデータベース(同じスキーマが、異なるレコード)

問題を抱えているこれらのサーバーの両方でAとBを言う: 我々はsqlqueryの

Select * from Person where memberId=123456 

これを持っていますクエリは完全に実行され、サーバAで選択された行が返されます。 しかし、別のサーバBの同じクエリはすべてのレコードを返しません。

しかし、私は

Select * from Person where memberId='123456' 

に私のクエリを変更した場合(単一引用符に注意してください)

今では私に適切なレコードを返します。

memberIdのデータ型はnchar(100)です。技術的には、私は一重引用符を使用して比較する必要があることを理解しています。

しかし、なぜこれが起こっているのか理解したいですか?

更新: 1)両方とも全く同じスキーマを持ちます。

実際にこのクエリを動的に作成し、次いで

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)'を使用していますか? –

+0

これらのSQL Serverのバージョンはどれですか(どちらになりますか)。また、フィールドmemberIdの照合順序も同じですか? –

答えて

2

である: 2)の両方が

実際のコードと同じレコードを有しますクエリでレコードが返されないか、エラーが返されますか?

ncharフィールドに数字を入力できるようですが、最初に文字を追加すると、もう "整数"をクエリできなくなります...または少なくともそうだと思われます。明らかにmemberId

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

は比較の前にintに変換されます(私は第二のマシン上のクエリ幹部に誤りがないと仮定します?)。だから私の最初の推測は、これはSql Serverの文化固有の機械である、つまりmemberIdは最初のマシン上でintに変換することができ、他にはできないということです。または、レコードが異なるため(?)、2番目のマシンに「間違った」レコードがいくつかあります。ただし、最後に実行時エラーが発生するはずです。

+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)エラーが発生返されます。だから、あれば、あなたのコードは、次のように見えた:あなたが得るでしょう

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があり、エラーを処理しているコードからSQLが呼び出されていると推測しています。 'CAST(memberId AS INT)'テストを実行されたとき、おそらく問題のストアドプロシージャ内ではなく、クエリウィンドウから実行しました。 –