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

我应该在SQL中引用数字吗?,sql,Sql,我记得读过关于在执行SQL查询时引用东西的内容,当您引用某个东西时,它会变成一个字符串。我还读到不应引用数字。现在,我找不到那个引号,我需要刷新我的记忆,看看我是否应该引用数字。如果要将数字视为数字,就不应该引用数字 记住它是一个字符串,你是对的 SELECT 10 AS x 是完全合法的,将返回(在大多数数据库引擎中)一列数据类型int(或其变体) 如果您这样做: SELECT '10' AS x 相反,您将得到一个文本数据类型。在某些情况下,这可能也很合适,但您需要决定是将结果作为文本还

我记得读过关于在执行SQL查询时引用东西的内容,当您引用某个东西时,它会变成一个字符串。我还读到不应引用数字。现在,我找不到那个引号,我需要刷新我的记忆,看看我是否应该引用数字。

如果要将数字视为数字,就不应该引用数字

记住它是一个字符串,你是对的

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

如果您这样做:

SELECT '10' AS x

相反,您将得到一个文本数据类型。在某些情况下,这可能也很合适,但您需要决定是将结果作为文本还是数字。

我不知道您可能读过什么,但不要引用数字。

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

选择1<1.0;//返回0
选择“1”<“1.0”;//返回1
这是因为第二次比较是使用当前字符串排序规则执行的,而不是使用数字


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

呃。。。不,你不应该

我想你指的是像“this”这样在
中加引号

插入表(foo)值(999)就完全合法

插入表(foo)值('foo')将字符串foo插入表中。当然,不能在INT类型的表上执行此操作。

显然,不要忘记检查您传递的任何值是否真的是一个数字。

好吧,冒着点燃火焰的风险,我是否有点不同意在数值周围使用单引号是永远不好的?在我看来,有时在数值周围使用单引号是有意义的。如果col1是一个INT列,那么(以vbscript为例)


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

这个答案适用于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);
}
但是您可以用任何语言编写相同的基准测试。我对引用的案例和未引用的案例运行了几次,并没有观察到速度上的显著差异。(在我的设置中,一次运行大约需要10秒钟;显然,您可以更改
$n
,使其更快或更慢。)

当然,如果生成的SQL中有多余的引号字符,那么它会更大。它当然不能再快了,但它似乎没有明显的慢

考虑到这个结果,我将简化SQL生成代码,在所有值周围添加单引号,而不需要知道要插入的列的数据类型。(代码仍然需要通过确保输入值本身不包含“字符”或巧妙地引用来防止SQL注入。)


我仍然不建议在正常情况下在SQL中引用数字,但如果您发现必须这样做,它似乎不会造成任何伤害。类似地,在生成的代码中,我把代码> []/COD>围绕列名称,不管是否需要,但是我认为手写SQL中的不必要的CRUCT. 取决于值在数据库中的存储方式。如果存储为文本,请将其引用;如果存储为数字,请不要:-)这不是数字,这是代码。比如产品ID或类似的。数字是你用来计算的东西。数字不应该被引用,因为数字永远不应该作为字符串存储在数据库中。@有人告诉你,由数字组成的ID不是数字,因此应该被引用,你的定义来源是什么吗?如果它是一个ID,对应于表中的行,比如1中的行,那么对于大多数db引擎来说,单引号可以吗?此时尤其是Postgres。数字主键也属于此定义。它们只包括数字,但它们是代码。在主键周围加引号有意义吗?不,没有。我删除了答案的最后一部分,因为这是一个观点,不适合作为答案。
sql = "INSERT '" & foo & "' INTO col1 WHERE ID = 1"
insert into #t values (123, 123, 123), (123, 123, 123)
insert into #t values ('123', '123', '123'), ('123', '123', '123')
$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);
}