1

我正在开发一个从 MS SQL Server 2008 或 2008 R2 服务器读取值的 C# 项目。

查询看起来像这样:

string charge="1234567";
string command = string.Format("SELECT * FROM tableX WHERE chargeField = '{0}' ", charge);

chargeField 来自 nvarchar(50) 类型 - 不要问我为什么 - 我无法更改数据库。此外,这些条目是由另一个我也无法更改的工具写入数据库的。有时,chargeField 值中会有前导或结束空格字符,所以我的查询不会返回任何内容,因为 "1234567" != " 1234567 "

但是,当我编写这样的查询时(没有''):

string command = string.Format("SELECT * FROM tableX WHERE chargeField = {0} ", charge);

有用。为什么这甚至可以工作-不需要''符号来指示数据库字段是字符串?我可以安全地更改所有查询吗?这是来自 MS SQL Server 的“功能”吗?这里到底发生了什么。

编辑

我通过使用解决了这个问题:

string command = string.Format("SELECT * FROM tableX WHERE RTRIM(LTRIM(chargeField)) = {0} ", charge);

谢谢。

4

2 回答 2

1

SQL Server 尝试相应地转换字段。如果没有引号,您将传入一个数字,因此 SQL Server 会尝试将值转换chargeField为数字,尽管有前导空格,这仍然有效。

chargeField如果包含 value ,这将不起作用12345a。这将导致转换错误。表中的一条记录包含这样的值就足以得到错误。

为了安全起见,请将您的查询更改为

... WHERE LTRIM(chargeField) = '{0}'

但请注意,这会导致字段上的可能索引不再被使用。您仍然可以做的是创建一个额外的列,该列使用值为 的触发器填充LTRIM(chargeField),在该列上放置一个索引并WHERE相应地调整您的子句。

于 2012-12-06T11:49:21.743 回答
1

数据类型优先规则:

当运算符组合不同数据类型的两个表达式时,数据类型优先级规则指定将具有较低优先级的数据类型转换为具有较高优先级的数据类型

Numeric/int 优先级高于 nvarchar,因此查询相当于:

SELECT * FROM tableX WHERE CAST(chargeField as INT) = {0}

请注意,这样的查询不能在chargeField.

于 2012-12-06T11:50:53.463 回答