我应该在SQL中引用数字吗?

时间:2010-01-16 21:18:20

标签: sql

我记得读过在做SQL查询时引用的东西,当你引用某些东西时,它变成了一个字符串。我还读到不应该引用数字。现在,我找不到报价,我需要刷新记忆,看看我是否应该引用数字。

7 个答案:

答案 0 :(得分:14)

你不应该引用数字。

你记得它是一个字符串是正确的。

SELECT 10 AS x

是完全合法的,并且将返回(在大多数数据库引擎中)数据类型为int的列(或其变体。)

我注意到Adam对你的问题的评论,我想对此发表评论,但我会编辑这个答案,因为我认为这是一个重点。

在SQL中引用“数字”通常在它不是数字时进行,而是在代码中进行。

通过数字我的意思是你可以计算,求和,计算,代码是一个标识符。

所以SSN是一个代码,它是你唯一的代码(我知道,N代表“数字”,如果你问我,有点用词不当),但你不会试图计算所有SSN的平均值在数据库中。

如果您将产品ID作为字符串存储在数据库中,但实际上它们只是由数字组成,那么它们是代码,而不是数字。

代码应该引用,数字不应该。

答案 1 :(得分:6)

这是一个例子,引用会产生不一致的结果(在MySQL中):

select 1 < 1.0;      // returns 0

select '1' < '1.0';  // returns 1

那是因为第二次比较是使用当前字符串排序而不是数字来执行的。

最好不要引用数字,因为这只是一个额外的不必要的步骤,数据库将字符串文字转换为数字值进行比较,并可能改变比较的含义。

答案 2 :(得分:4)

这个答案适用于Microsoft SQL Server,特别是MSSQL 2008 R2。

在手写SQL中,我永远不会引用数字(除非将值插入到varchar列中,其中插入的字符串恰好是一个数字)。但有时当以编程方式生成SQL时,它可以简化引用一切的生活。 (这是在任何表上工作的数据库维护脚本或库例程,而不事先知道列类型。)

我想知道这样做是否会造成性能损失。如果我在我的SQL语句中使用了引用值,则服务器必须将其解析为字符串,然后必须将其转换为整数。但是,解析SQL无论如何都会涉及将字符串转换为整数。查询解析时间通常只占总数的一小部分。

我运行了一些看起来像

的测试语句
insert into #t values (123, 123, 123), (123, 123, 123)
insert into #t values ('123', '123', '123'), ('123', '123', '123')

#t中的列数较多,一次插入的元组元组数量较多,每个语句重复多次。我碰巧使用Perl:

$dbh = my_database_connection(); # using DBD::Sybase
$n = 20; # this many value tuples, and also repeated this many times
$v = "'123'";
# $v = 123;    # uncomment this to insert without quoting

@cols = 'aa' .. 'zz';
@ds = map { "[$_] int not null" } @cols;
@vs = map { $v } @cols;
$" = ", ";
$dbh->do("create table #t (@ds)");
foreach (1 .. $n) {
    $sql = 'insert into #t values ';
    $sql .= "(@vs), " foreach 1 .. $n;
    $sql =~ s/, \z//;
    $dbh->do($sql);
}

但您可以用任何语言轻松编写相同的基准。我为引用的案例和未引用的案例运行了几次,并且观察到速度没有显着差异。 (在我的设置中,单次运行大约需要十秒钟;显然可以更改$n以使其更快或更慢。)

当然,如果生成的SQL中包含冗余引号字符,则它会更大。它肯定不会更快,但它似乎没有明显变慢。

鉴于此结果,我将简化我的SQL生成代码,在所有值周围添加单引号,而无需知道要插入的列的数据类型。 (代码仍然需要通过确保输入值本身不包含'字符,或以其他方式巧妙地引用来防御SQL注入。)

我仍然不建议在正常情况下在SQL中引用数字,但如果你发现必须这样做,它似乎不会造成任何伤害。类似地,在生成的代码中,我将[]放在列名称周围,无论是否需要,但我认为手写SQL中存在不必要的错误。

答案 3 :(得分:1)

我不知道你读过什么,但不引用数字。

答案 4 :(得分:1)

显然,不要忘记检查以确保您传递的任何值确实是一个数字。

答案 5 :(得分:0)

呃......不,你不应该?

我认为你的意思是引用封闭在 ' like 'this'

只要foo是INT类型的列,

INSERT INTO table (foo) VALUES (999);就完全合法 INSERT INTO table (foo) VALUES('foo');将字符串foo插入表中。当然,你不能在INT类型表上执行此操作。

答案 6 :(得分:0)

那么,冒着点燃火焰的风险,我在这里可能会有点不同意,在数字值周围使用单引号绝对没问题吗?在我看来,有时在数值周围使用单引号是有意义的。如果col1是INT列,那么(以vbscript为例)

sql = "INSERT " & foo & " INTO col1 WHERE ID = 1"

sql = "INSERT '" & foo & "' INTO col1 WHERE ID = 1"

将同时执行sql时,正确插入foo的任何整数值。但是如果你想在foo未初始化时插入0,该怎么办?使用这样的带引号的数字表达式可以防止错误并处理null情况。无论你是否认为这是一种好的做法,这当然是正确的。