【问题标题】:MySQL - How to insert a possibly null valueMySQL - 如何插入一个可能为空的值
【发布时间】:2011-11-29 00:26:27
【问题描述】:

我在 PHP 脚本中有一些值必须插入到 MySQL 表中。例如 3 个日期 d1d2d3

我有将值插入数据库的默认语句:

insert into mytable set a=1, b=2, d1='$val', d2='$val2', d3='$val3'

如果$val1$val2$val3 中的一个(或多个)为 nil,是否有一种非常简单的方法可以编写 SQL 语句以插入 d1、d2 和 d3 NULL 值而不是日期?无需处理新的 PHP 变量?

【问题讨论】:

    标签: php mysql insert null


    【解决方案1】:

    假设您在$data 数组中拥有所有内容:

    $query_string = "insert into mytable set a=1, b=2, d1=" .
        (isset($data['val1']) ? "'" . $data['val1'] . "'" : 'NULL') . ", d2=" .
        (isset($data['val2']) ? "'" . $data['val2'] . "'" : 'NULL') . ", d3=" .
        (isset($data['val3']) ? "'" . $data['val3'] . "'" : 'NULL') . ";";
    

    字符串将包含例如。如果数组中的值不存在或等于null,则d2=NULL 而不是d2='xyz'

    您还必须确保要粘贴到查询中的字符串已正确清理(例如,使用mysql_real_escape_string())。 我的回答将您的变量视为已经准备好并经过清理,因为您只想知道如何插入 NULL 值而不是您拥有的变量。

    因为问题只是关于根据变量值在查询中输入NULL 值,所以我认为在这里详细讨论清理不是一个好主意。您可以在此处找到有关 SQL 注入以及如何在 PHP 中防止它的更多详细信息:Best way to stop SQL Injection in PHP。祝你好运! :)

    【讨论】:

    • @Kenaniah:你在说什么参数注入?为未来的读者解释自己。如果您谈论的是 SQL 注入,那么我相信您的反对意见是基于数据没有被转义的假设。我没有做出这样的假设 - 我回答了 OP 的问题。
    • $data[$x] 未正确转义以处理引用问题。例如,如果$data['val1'] 包含',则您的查询将不再正确运行,然后会受到恶意注入攻击。
    • @Kenaniah:正如我所说,你拒绝了我的回答,因为我没有逃避数据,即使你有没有理由相信数据没有被清理!如果 OP 示例中的 $val1$val2$val3 都是整数或 NULL 怎么办?你要杀死我了。 Assumption is a mother of all screw ups。我回答了这个问题,不认为它是用户提供的数据。
    • @Kenaniah:曾经看到过不必要的双重转义的数据吗?这个问题很准确,但是我会在答案中加入适当的信息。但正如 OP 所说,该应用程序已经存在,无论他为清理数据所做的一切都是他所关心的。由于您的假设,您对正确答案投了反对票。最糟糕的是,这不是因为答案不正确,而是因为它没有执行您认为应该做的事情;)干杯!
    • @Kenaniah:我没说用<?php打开脚本,关于脚本应该放在哪里,应该使用什么授权/认证机制,为什么将数据存储在原始cookie中可以危险,什么是 CSRF 或 XSS,哪个 PHP 框架更好,mod_rewrite 是什么,JavaScript 是做什么用的。它是否使我的答案不正确?不,等等,也许是? SO是关于提问和回答问题。我已经回答了一个问题,我没有尝试为 OP 编写整个应用程序;)但幸运的是,您是来做这件事的 :)
    【解决方案2】:

    可能有更好的方法来做到这一点,但如果所有其他方法都失败了,你可以用你的每个值来做到这一点:

    $val = isset($val) ? "'$val'" : "NULL";
    

    然后将您的 PHP 查询字符串更改为:

    insert into mytable set a=1, b=2, d1=$val, d2=$val2, d3=$val3
    

    您应该考虑使用prepared statementsPDO 而不是构建这样的查询字符串,尤其是在您的变量中涉及用户输入的情况下。

    【讨论】:

    • 奥利弗,us2.php.net/pdo。请在尝试编程之前阅读手册。
    • 谢谢。我会考虑的……总有一天。事实上,我不是 php 的新手,但每次发布新版本的 php 时,我都没有时间阅读完整的文档。我用 PHP 3.0 开发了一个网站,它可以工作,我只想维护它,而不是从头开始重写它以实现我目前不需要的非常酷的额外功能。
    【解决方案3】:

    最简单的就是定义

    function esc_null($src) {
        return $src === null ? 'NULL' : ("'" + mysql_real_string_escape($src) + "'");
    }
    
    "insert into mytable set a=1, b=2, d1=" . esc_null($val) . ", d2=" . esc_null($val2) . ", d3=" . esc_null($val3)
    

    这也可以确保您的查询的完整性。

    【讨论】:

    • 您的解决方案确保如果$val 等于nil,则将在查询中插入以下字符串:“d1='NULL'”。如果您没有发现差异:这是一个 4 字母字符串“NULL”,而不是实际的 NULL 值。
    • -1 用于参数注入问题。也适用于nil。 PHP 使用null
    • @Kenaniah:好的,但经过一些修改,这可能是一个很好的答案。
    • @Oliver:当然可以,但是当$val等等于NULL时,它应该插入NULL而不是'NULL'
    • 糟糕。我现在改变了它,希望它是正确的。我脑子里已经有了这个“'”的东西。但是,@Kenaniah、AFAICT nil'NULL' 而不是 NULL 是唯一的问题。哪里/那里有参数注入问题?我在所有变量周围都有mysql_real_escape()(我的意思是什么)。哪里可以注入东西?
    【解决方案4】:

    我发现这种方式是做我想做的最简单的方式:

    INSERT INTO mytable SET a=1, b=2, d1=IF('$val' = '', NULL, '$val');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-01
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多