SQL Server |字符串比较

时间:2011-09-09 08:41:33

标签: sql-server-2005 sql-server-2008 string-comparison

我正面临一些奇怪的问题,并想了解背后的原因。

我们有两个数据库服务器说A和B.在这两个服务器上我们都有我们的应用程序数据库(相同的模式但不同的记录)

问题: 我们有一个SqlQuery

Select * from Person where memberId=123456

此查询运行完美并返回在服务器上选择的行 - A. 但是在不同服务器-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)

3 个答案:

答案 0 :(得分: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 

答案 1 :(得分: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块,也可能发生这种情况。但是,如果我们更改记录的顺序 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 :(得分:0)

显然memberId在比较之前转换为int(我假设第二台机器上的查询执行程序中没有错误?)。所以我的第一个猜测是这是特定于Sql Server文化的机器,即memberId可以在第一台机器上转换为int而在其他机器上不能转换为int。或者,由于记录不同(?),第二台机器上只有一些“错误”的记录。但最后一件事应该导致运行时错误。