Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL中非空列中的空字符串?_Php_Mysql_Mysqli_Nullable_Prepared Statement - Fatal编程技术网

Php MySQL中非空列中的空字符串?

Php MySQL中非空列中的空字符串?,php,mysql,mysqli,nullable,prepared-statement,Php,Mysql,Mysqli,Nullable,Prepared Statement,我曾经使用标准的mysql\u connect()、mysql\u query()等语句从PHP中执行mysql内容。最近,我开始使用出色的MDB2类。除此之外,我还使用准备好的语句,因此我不必担心逃避输入和SQL注入攻击 然而,我遇到了一个问题。我有一个表,其中有几个VARCHAR列,它们被指定为NOTNULL(即不允许null值)。使用旧的MySQL PHP命令,我可以毫无问题地执行以下操作: INSERT INTO mytable SET somevarchar=''; 但是,现在,如果

我曾经使用标准的mysql\u connect()、mysql\u query()等语句从PHP中执行mysql内容。最近,我开始使用出色的MDB2类。除此之外,我还使用准备好的语句,因此我不必担心逃避输入和SQL注入攻击

然而,我遇到了一个问题。我有一个表,其中有几个VARCHAR列,它们被指定为NOTNULL(即不允许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值违反非null约束”

作为临时解决方法,我检查
$value
是否为空,并将其更改为
(单个空格),但这是一个可怕的黑客行为,可能会导致其他问题

我应该如何插入带有准备语句的空字符串,而不尝试插入NULL

编辑:这个项目太大了,无法遍历我的整个代码库,找到所有使用空字符串“”的地方,并将其改为使用NULL。我需要知道的是,为什么标准的MySQL查询将“”和NULL视为两个独立的东西(我认为这是正确的),而prepared语句将“”转换为NULL


请注意,“”和NULL不是同一件事。例如,
SELECT NULL=“”
返回
NULL
,而不是像您预期的那样返回
1

一组空引号,
不是这样做的吗?

我很困惑。看起来您使用的是mysqli OO(从标记和样式来看),但语法与php.net上的不同,后者表示要执行以下操作:

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();

这听起来像是MDB2 API混淆PHP的duck类型语义的问题。因为PHP中的空字符串相当于NULL,所以MDB2可能错误地将其视为NULL。理想的解决方案是在它的API中为它找到一个解决方案,但我对它不太熟悉

<>你应该考虑的一件事是SQL中的空字符串不是空值。您可以将它们插入声明为“NOTNULL”的行中,这很好:

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中找到(或实现)一个解决方案,一个黑客解决方案(尽管比您当前使用的解决方案稍好)可能是为空字符串定义一个--


最后,如果您需要在INSERT语句中使用空字符串,但发现自己无法使用,则MySQL中字符串类型的默认值为空字符串。因此,您只需从INSERT语句中省略该列,它就会自动设置为空字符串(前提是该列具有NOTNULL约束)。

由于一些答案,我意识到问题可能出在MDB2 API中,而不是PHP或MYSQL命令本身。果然,我在MDB2常见问题解答中找到了这一点:

  • 为什么空字符串在数据库中以NULL结尾?为什么我会得到一个空值 不允许在非空文本字段中使用 即使默认值为“”?
    • 问题是,对于某些RDBMS(最值得注意的是Oracle)来说,一个空的 字符串为空。因此MDB2 提供可移植性选项,以 对所有人实施同样的行为 关系数据库管理系统
    • 由于默认情况下启用了所有可移植性选项,因此您将 要禁用此功能,请执行以下操作: 想要有这种行为: $mdb2->setOption(“可移植性”, MDB2_可移植性_所有^ MDB2_可移植性_空_到_空)

感谢每一位提供了深思熟虑的答案的人。

我意识到这个问题已经基本上得到了回答,并且已经退休了,但我是在寻找类似情况的答案时发现的,我忍不住要参加比赛

如果不知道NULL/“”列与什么相关,我就无法知道空字符串的真正意义。空字符串本身意味着什么吗(比如,如果我说服法官让我把我的名字改成什么都没有,如果我的名字在我的驾照上显示为空,我会非常生气。我的名字会是空的

然而,空字符串(或空白,或虚无,而不仅仅是缺少任何东西(如NULL))也可能只是表示“不为NULL”或“无,但仍然不为NULL”。你甚至可以换个方向,建议如果没有NULL值,它甚至比NULL还小,因为至少NULL有一个你可以大声说出的名字

我的观点是,如果空字符串是某些数据的直接表示形式(如姓名,或者我更喜欢在电话号码中的数字之间插入的内容等),那么您的选择要么是争论直到您对空字符串的合法使用感到愤怒,要么是使用表示非空字符串的内容(如ASCII控制字符或某些unicode等效字符、某种类型的正则表达式值,或更糟糕的是,任意但完全未使用的标记,如:◘

如果空单元格真的只是表示NOT NULL,那么你可以考虑其他的表达方式。一种愚蠢而明显的方式是短语“NOT NULL”。但我有一种预感,NULL表示“根本不属于这个群体”,而空字符串表示“这家伙很酷,他只是还没有得到他的帮派纹身”.在这种情况下,我会为这种情况想出一个术语/名称/想法,比如“默认”或“新手”或“待定”

现在,如果有一个疯狂的机会,你真的想要空字符串来表示那些甚至不值得为NULL的字符串,再一次,想出一个更重要的符号,比如“-1”或“SUPERNULL”或“UGLIES”

在印度种姓制度中,最低的种姓是Shudra:农民和劳工。在这个种姓之下是贱民:“贱民”。他们不被考虑
SET @EMPTY_STRING = "";
UPDATE tbl SET row=@EMPTY_STRING;
$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:password@server/dbase", $options);