在MySQL中的整数字段上运行带引号(字符串)的查询时会出现什么复杂情况

Ram*_*ker 5 mysql sql type-conversion

在SQL中,您不应该引用整数,因为如果引用,它将是一个字符串.

但我很好奇如果我这样做会出现什么问题/并发症?

例如:(
SELECT * FROM table WHERE id = 1正确)

SELECT * FROM table WHERE id = '1'(不正确)

Ps在这个问题上没有找到任何重复.如果有,请纠正我

You*_*nse 8

这是一个有趣的问题,我花了很多时间研究可能的结果(对于mysql).

到目前为止,我只能找到1,5个缺点:

  • 首先,如果在查询中将一个操作数作为字符串发送,则对BIGINT值执行数学运算或比较运算会得到奇怪的结果- 因为在这种情况下,两个操作数都将转换为浮点值,从而丢失精确.这是一个演示代码.只需运行这些查询并检查结果,这非常令人尴尬:

    create table bint(i bigint);
    insert into bint values (18014398509481984);
    update bint set i=i+'1';
    update bint set i=i+1
    update bint set i=i+'1'
    
    Run Code Online (Sandbox Code Playgroud)

    但是,对于仅选择或更新BIGINT值,在查询中引用它们或在预准备语句中绑定为字符串仍然没有问题.

  • 其次,我只算是问题的一半,因为我仍然无法找到一个好的证据.但是DBA坚持认为有一些神秘的查询非常复杂,以至于错误的数据类型可能会破坏优化器,并会选择错误的执行计划.然而,在我15年的经验中,我找不到运气.我将把最大的赏金给予能够提供可再现证明的答案,而不仅仅是过去的好时光.

所以你可以告诉我,对于常规数据类型的常规查询,绝对没有区别.

语法上唯一不允许字符串操作数的查询部分是LIMIT子句:a LIMIT '1'将导致语法错误.

但是,使用预准备语句,如果将LIMIT参数绑定为字符串,它将执行所有操作:

$stmt = $mysqli->prepare("SELECT value FROM table LIMIT ?");
$stmt->bind_param("s", $limit);
Run Code Online (Sandbox Code Playgroud)

将毫无错误.

  • `LIMIT`案例特别有趣,似乎是一个SQL解析器问题(如你所说,绑定参数不受影响).因此,如果`PDO :: ATTR_EMULATE_PREPARES`为'false`,它只能在PDO中工作. (2认同)