我用的标准mysql_connect(),mysql_query()等报表做MySQL的东西从PHP.最近我已经换过来使用美妙的MDB2类。沿着它,我使用准备好的发言,因此我不必担心逃避我的输入和SQL注射攻击。

然而,还有一个问题我运行。我有一个表与几VARCHAR columns,被指定为不null(即,不允许空值)。使用旧MySQL PHP命令,我可以做这样的事情没有任何问题:

INSERT INTO mytable SET somevarchar = '';

然而,现在,如果我有一个的查询,如:

INSERT INTO mytable SET somevarchar = ?;

然后在PHP我有:

$value = "";
$prepared = $db->prepare($query, array('text'));
$result = $prepared->execute($value);

这将引发错误"null value violates not-null constraint"

作为一个临时的解决办法的,我查查 $value 是空的,并改变它 " " (一个单一的空间),但这是一个可怕的黑客和可能会引起其他问题。

我怎么插入空串用准备好的发言,而不试图,而不是插入一个空?

编辑: 它太大的一个项目,以通过我的整个代码,找到处使用的an empty string""并将其更改为使用空替代。什么我需要知道的是为什么标准MySQL查询的治疗","NULL作为两个单独的事情(我认为是正确的),但准备好的发言将"的"进入空。

注意到","NULL是 同样的事情。例如, SELECT NULL = ""; 返回 NULL 而不是的 1 如你所期望的。

有帮助吗?

解决方案

这听起来像是MDB2 API愚弄PHP的鸭子类型语义的问题。因为PHP中的空字符串等于NULL,所以MDB2可能会错误地处理它。理想的解决方案是在其API中找到解决方法,但我并不过分熟悉它。

但是,您应该考虑的一件事是SQL中的空字符串不是NULL值。你可以将它们插入声明为'NOT NULL'的行中就好了:

mysql> CREATE TABLE tbl( row CHAR(128) NOT NULL );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tbl VALUES( 'not empty' ), ( '' );
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT row, row IS NULL FROM tbl;
+-----------+-------------+
| row       | row IS NULL |
+-----------+-------------+
| not empty |           0 | 
|           |           0 | 
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO tbl VALUES( NULL );
ERROR 1048 (23000): Column 'row' cannot be null

如果您无法在MDB2 API中找到(或实施)变通方法,那么一个hackish解决方案(虽然稍微好于您当前使用的解决方案)可能是定义用户变量为空字符串 -

SET @EMPTY_STRING = "";
UPDATE tbl SET row=@EMPTY_STRING;

最后,如果您需要在INSERT语句中使用空字符串但发现自己无法使用,则MySQL中字符串类型的默认值为空字符串。所以你可以简单地省略INSERT语句中的列,它会自动设置为空字符串(假设列有一个NOT NULL约束)。

其他提示

由于一些答案,我意识到这个问题可以在MDB2API,而不是在PHP或MYSQL命令本身。肯定够了,我发现这个的MDB2常见问题:

  • 为什么空串结束了作为空中的数据库?为什么我得到一个空 不允许在没空文本田 尽管默认值是""?
    • 问题是,对于一些RDBMS(最noteably Oracle)一个空的 string is NULL.因此MDB2 提供一个可移植性选择 强制执行相同行为的所有 RDBMS。
    • 由于所有可携带性的选择是默认你将拥有 以禁止的特征,如果你不 希望有这样的行为:$mdb2->setOption('携带', MDB2_PORTABILITY_ALL^ MDB2_PORTABILITY_EMPTY_TO_NULL);

感谢大家提供了周到的答复。

我意识到这个问题已得到很好的回答和退休,但我在寻找类似情况的答案时找到了它,我无法抗拒将我的帽子戴在戒指上。

不知道NULL /""列涉及到,我不知道空字符串的真正意义如何。空字符串本身就意味着什么(就像,如果我说服一位法官让我改变我的名字,我会非常恼火,如果我的名字出现在我的驾驶执照上为NULL。我的名字就是!

然而,空字符串(或空白,或者是SOMETHING的虚无,而不仅仅是缺少任何东西(如NULL))也可能只是意味着“NOT NULL”。或“没什么,但仍然不是空”。你甚至可以走向另一个方向,并建议缺少值NULL使它甚至比Null更少,因为至少Null有一个你可以大声说出的名字!

我的观点是,如果空字符串是某些数据的直接表示(如姓名,或者我喜欢插入电话号码中的数字之间等),那么您的选择要么是争论直到你'为了合法使用空字符串而感到痛苦,或者使用表示非空的字符串的东西(就像一个ASCII控制字符或一些unicode等价物,某种类型的正则表达式,或者更糟糕的是,是一种任意的完全未使用的令牌,如:◘

如果空单元格实际上只是意味着NOT NULL,那么你可以想出一些表达它的方法。一个愚蠢而明显的方式是短语“Not NULL”。但我有一种预感,即NULL意味着“根本不属于这个群体的一部分”。虽然空字符串意味着“这个家伙很酷,他还没有得到他的帮派纹身”。在这种情况下,我会针对这种情况提出一个术语/名称/想法,例如“默认”和“默认”。或“菜鸟”或“菜鸟”或“待定”。

现在,如果有一些疯狂的机会你真的希望空字符串代表那些甚至不值得为空的字符串,那么再次为它提出一个更重要的符号,例如“-1”和“-1”。或“SUPERNULL”或或“UGLIES”。

在印度种姓制度中,最低的种姓是Shudra:农民和劳动者。在这个种姓之下是达利特:“不可触犯的”。它们不被认为是较低的种姓,因为将它们设置为最低种姓将被视为整个系统的污染。

所以不要因为我认为空字符串可能比NULL更糟糕而感到疯狂!

'下一次。

我找到了解决方案!

MDB2将空字符串转换为NULL,因为默认情况下可移植性选项MDB2_PORTABILITY_EMPTY_TO_NULL处于启用状态(感谢Oracle认为空字符串为空)。

连接数据库时关闭此选项:

$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:password@server/dbase", $options);

当0和空字符串是变量时,NULL是缺少数据。相信我,将查询写入

要容易得多

SELECT * from table from mything IS NULL 而不是尝试查询空字符串:/

不是一组空引号,"" 吗?

我很困惑。看起来你正在使用mysqli OO(来自标签和样式),但语法不同于手册,它代表这样做:

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top