SQL Server | Сравнение строк - PullRequest
       34

SQL Server | Сравнение строк

3 голосов
/ 09 сентября 2011

Я столкнулся с какой-то странной проблемой и хочу понять причину этого.

У нас есть два сервера базы данных, скажем, A и B. На обоих этих серверах у нас есть база данных приложений (та же схема, но разные записи)

Проблема: У нас есть SqlQuery

Select * from Person where memberId=123456

Этот запрос выполняется отлично и возвращает строки, выбранные на сервере - A. Но тот же запрос на другом сервере-B не возвращает никаких записей.

Но если я изменю свой запрос на

Select * from Person where memberId='123456' 

(обратите внимание на одинарные кавычки)

Теперь он возвращает мне правильные записи.

DataType memberId равен nchar (100). Технически я понимаю, что я должен сравнить это, используя одинарные кавычки.

Но просто хочу понять, почему это происходит ??

Обновление: 1) Оба имеют одинаковую схему. 2) Оба имеют одинаковые записи

Фактический код:

На самом деле этот запрос динамически создается и затем выполняется с использованием

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

и этот параметр @MemberId равен varchar (250)

Ответы [ 3 ]

2 голосов
/ 10 сентября 2011

Мне будет очень интересно узнать, если вы придумаете другую причину, по которой это происходит, но я начинаю сомневаться в этом.Я вполне уверен, что вы где-то ловите или подавляете ошибку.

Примите во внимание следующее:

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.Однако, если мы изменим порядок 1 записей:

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.Кластерные индексы не гарантируют порядок строк .Это почти наверняка будет в этом тесте, но это стоило указать.

2 голосов
/ 09 сентября 2011

Запрос не возвращает записей или выдает ошибку?

Похоже, вы можете вводить числа в поле 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 голосов
/ 09 сентября 2011

Очевидно, memberId преобразуется в int перед сравнением (я полагаю, что нет ошибок в запросе exec на 2-й машине?). Таким образом, мое первое предположение могло бы состоять в том, что это машина специфичной для Sql Server культуры, то есть memberId может быть преобразовано в int на первой машине, а не на другой. Или, поскольку записи различаются (?), На 2-й машине есть просто «неправильные» записи. Однако последнее должно привести к ошибке во время выполнения.

...