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

amb*_*use 22 sql

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

ang*_*son 15

你不应该引用数字.

通过记住它使它成为一个字符串你是正确的.

SELECT 10 AS x
Run Code Online (Sandbox Code Playgroud)

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

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

在SQL中引用"数字"通常是在它不是真正的数字而是代码时完成的.

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

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

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

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


jsp*_*cal 6

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

select 1 < 1.0;      // returns 0

select '1' < '1.0';  // returns 1
Run Code Online (Sandbox Code Playgroud)

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

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


Ed *_*vis 6

此答案适用于 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')
Run Code Online (Sandbox Code Playgroud)

但是由于 中的列数较多#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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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