sql查询将int视为字符串 - 问题?

时间:2015-10-06 08:00:06

标签: c# sql .net

如果我这样做一个查询

SELECT * from Foo where Bar = '42'

和Bar是一个int列。在db引擎中,该字符串值是否会优化为42?如果我保留原样而不是将其更改为:

,它会产生某种影响吗?
Select * from Foo where Bar = 42  

如果这会产生影响,则在SQL Compact数据库上完成 我知道它不是正确的方法,但是通过所有代码查看每个查询和数据库模式以查看列是否为int类型,这是一个巨大的痛苦。

5 个答案:

答案 0 :(得分:3)

SQL Server 会自动将其转换为INT因为INT higher precedence而不是VARCHAR

  

您还应该了解隐式转化可能带来的影响   有查询的性能。为了证明我的意思,我在AdventureWorks2008数据库中创建并填充了下表:

USE AdventureWorks2008;

IF OBJECT_ID ('ProductInfo', 'U') IS NOT NULL
DROP TABLE ProductInfo;

CREATE TABLE ProductInfo
(
  ProductID NVARCHAR(10) NOT NULL PRIMARY KEY,
  ProductName NVARCHAR(50) NOT NULL
);

INSERT INTO ProductInfo
SELECT ProductID, Name
FROM Production.Product;
  

如您所见,该表包含一个配置了主键的主键   NVARCHAR数据类型。因为ProductID列是主键,   它将自动配置聚簇索引。接下来,我   将统计信息IO设置为on,以便查看有关磁盘的信息   活性:

SET STATISTICS IO ON;
  

然后我运行以下SELECT语句来检索产品   产品信息350:

SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = 350;
  

由于启用了统计信息IO,因此我的结果包括以下内容   信息:

     

表'ProductInfo'。扫描计数1,逻辑读取6,物理读取0,   预读读取0,lob逻辑读取0,lob物理读取0,lob   预读读取0。

     

要注意的两个重要事项是查询执行扫描和   它需要六次逻辑读取来检索数据。因为我的WHERE   子句在主键列中指定了一个值作为其中的一部分   搜索条件,我本来期望索引寻求执行,   而不是我扫描。如下图所示,数据库引擎执行扫描,而不是搜索。下图显示了该扫描的详细信息(通过将鼠标悬停在扫描图标上进行访问)。

convertion

  

请注意,在Predicate部分中,CONVERT_IMPLICIT函数是   用于转换ProductID列中的值   将它们与350的值(由@ 1表示)进行比较   WHERE子句。数据被隐式转换的原因   是因为我将350 in作为整数值传递,而不是字符串   值,因此SQL Server将所有ProductID值转换为   整数,以便进行比较。

     

因为ProductInfo表中的行数相对较少,   在这种情况下,性能不是很重要。但如果   你的表包含数百万行,你说的是严肃的   打击表现。当然,解决这个问题的方法就是通过   在350参数中作为字符串,正如我在下面所做的那样   例如:

SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = '350';
  

该语句再次返回产品信息和统计IO数据,如以下结果所示:

     

现在索引正确用于查找记录。如果你   请参阅下图,您将看到ProductID中的值   在进行比较之前,不再对列进行隐式转换   到搜索条件中指定的350。

enter image description here

  

正如此示例所示,您需要了解性能如何   可能会受到隐式转换的影响,就像您需要的那样   了解由...进行的任何类型的隐式转换   数据库引擎。出于这个原因,您通常会明确地想要   转换您的数据,以便您可以控制转化的影响。

您可以阅读有关Data Conversion in SQL Server的更多信息。

答案 1 :(得分:2)

如果查看告诉隐式转换的MSDN chart,您会发现该字符串被隐式转换为int。

enter image description here

答案 2 :(得分:0)

两者都适用于你的情况,但规范是使用报价。 因为这项工作。

从Foo中选择*,其中Bar = 42

这不是

从Foo中选择*,其中Bar =%42%

这将

来自Foo的SELECT *,其中Bar ='%42%'

ps:无论如何你应该看看实体框架和linq查询,它会让它变得简单......

答案 3 :(得分:0)

如果我没有弄错的话,如果字符串只包含数字(数字)并且你将它与INT列数据类型进行比较,那么SQL Server会将其读作INTEGER,但是如果string是字母数字,那么您将遇到错误或意外结果。

我的建议是,在WHERE条款中,如果您要比较integer,请不要单引号。这是避免错误和意外结果的最佳做法。

答案 4 :(得分:0)

You should use always parameters when executing sql by code, to avoid security lacks (EJ: Sql injection).