SQL Server |字符串比较
我面临一些奇怪的问题,并希望了解背后的原因。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)
查询是否返回记录或是否给出错误?
它看起来像你可以输入数字到一个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
OP的确切含义是它们只是没有结果而不是错误。这将是非常重要的一点信息! –
它不返回任何记录,没有错误/异常 – Gaurav
显然memberId
转换比较之前,INT(我假设有在2号机上查询EXEC没有错误?)。所以我的第一个猜测是,这是Sql Server文化特定的机器,即memberId
可以在第一台机器上转换为int,而不能在其他机器上转换为int。或者,由于记录不同(?),第二台机器上只有一些“错误”的记录。但最后一件事情应该会导致运行时错误。
Petr-不确定SQL服务器的文化具体的事情,导致这两个服务器都由我们的托管服务提供商 – Gaurav
我会很感兴趣知道你是否想出了为什么会发生这种情况的另一个原因,但我开始怀疑它。我相当肯定你在捕捉或压制某处的错误。
考虑以下几点:
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.群集索引不要保证行的顺序。它几乎肯定会在这个测试中,但值得指出。
我看不到任何方式,文字'123456'可能会导致所描述的行为。希望如果OP显示他们实际使用的价值将变得更清晰。 –
我的猜测是由123456或任何值引起的隐式转换为int导致错误。 OP说SQL是在一个存储过程中的,我猜测它是从正在处理错误的代码中调用的。当你让他做'CAST(memberId AS INT)'测试时,他可能是从查询窗口做出来的,而不是在问题存储过程中。 –
对不起,可能看起来像一个明显的问题,你再次检查两个表的模式是否相同? – GrandMasterFlush
有趣的问题,但为什么你使用固定宽度的200字节列'nchar(100)'来存储一个int? –
哪些SQL Server版本是这些(哪个是哪个)?另外,字段memberId的排序顺序是否相同? –