我正面临一些奇怪的问题,并想了解背后的原因。
我们有两个数据库服务器说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)
答案 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。或者,由于记录不同(?),第二台机器上只有一些“错误”的记录。但最后一件事应该导致运行时错误。