PHP MySQL - 如何在准备好的语句中插入默认值
PHP MySQL - How to insert default value in a prepared statement
假设我有一个准备好的声明,如下所示:
$insertSql = "";
$insertSql .= "INSERT INTO table";
$insertSql .= "(tag,month_interval,month_interval_lastupdated,date_due,date_due_lastupdated,date_completion,date_completion_lastupdated,";
$insertSql .= "activeNotification,date_lastmodified) ";
$insertSql .= "VALUES (?,?,NOW(),?,NOW(),?,NOW(),?,NOW())";
但有时其中一些问号不会被设置。
我可以在准备好的语句中替换一个关键字来告诉 MySQL 插入默认值吗?
类似于:
if($stmt = $mysqli->prepare($insertSql)) {
if(!isset($tag)) {
// code to find first question mark and replace w/ default value
}
$stmt->bind_param('sisss',$tag,$month_interval,$date_due,$date_completion);
$stmt->execute();
}
日期字段的默认值为“1000-01-01 00:00:00”,month_interval 的默认值为 0,其余字段的默认值为 NULL。
想一想,如果您遇到不知道所有值的情况,您应该准备语句甚至不要添加这些值。
同样在一些情况下(例如在自动增量字段上)你可以插入一个NULL
这将触发要插入的默认值,BUT 如果字段定义允许 NULL's
插入 NULL
,请务必小心NULL
.
在我看来,你的问题涉及一个有趣的主题。
通过快速搜索,我没有找到任何预定义的解决方案,但我会在接下来的几天继续搜索。
我有一个详细的解决方案,但它有点扭曲而且不完全干净。
首先,我用占位符重新定义查询:
$query = "
INSERT INTO table
(
tag,
month_interval,
month_interval_lastupdated,
date_due,
date_due_lastupdated,
date_completion,
date_completion_lastupdated,
activeNotification,
date_lastmodified
)
VALUES (<tag>,<month_interval>,NOW(),<date_due>,NOW(),<date_completion>,NOW(),<activeNotification>,NOW())
";
在这个例子中,我使用 <>
来包围占位符,但您可以选择您喜欢的占位符,确保它们不会与查询的其他元素混淆。
然后,我初始化一个关联数组,其中键作为占位符名称和要绑定的值,以及一个具有完整绑定类型集的变量 ($types
):
$values = array( 'tag'=>$tag, 'month_interval'=>$month_interval, 'date_due'=>$date_due, 'date_completion'=>$date_completion, 'activeNotification'=>$activeNotification );
$types = 'sisss';
然后,最重要的一行。我以这种奇怪的方式初始化一个数组:
$bind = array( Null, '' );
索引 0 设置为 Null
,因为它是为 stmt
对象(下面创建的)保留的;索引 1 是一个空字符串,将填充必要的绑定类型。
现在我对数组 $values
:
的所有元素执行 foreach
循环
$i = 0;
foreach( $values as $key => $val )
{
if( is_null( $val ) )
{
$query = str_replace( '<'.$key.'>', 'DEFAULT', $query );
}
else
{
$query = str_replace( '<'.$key.'>', '?', $query );
$bind[1] .= $types[$i];
$bind[] = &$val;
}
$i++;
}
在该循环中,如果值为 null,我将相应查询的占位符替换为 mySQL 关键字 DEFAULT
。否则,我用 ?
替换占位符,将相应的 $types
子字符串添加到 $bind[1]
,并将值(通过引用)附加到 $bind
数组。
至此,真正的查询已经准备就绪,我可以准备了:
$stmt = $db->prepare( $query ) or die( $stmt->error );
并且,如果没有默认值(count($bind)>2
),我可以绑定它:
if( count($bind)>2 )
{
$bind[0] = $stmt;
call_user_func_array( 'mysqli_stmt_bind_param', $bind );
}
如前所述,我将$bind[0]
设置为->prepare
返回的stmt对象,然后我使用call_user_func_array
执行mysqli_stmt_bind_param
。我不能直接调用 ->bind_param
因为我有一个可变参数 number.
在这个古怪的过程结束后,我终于可以执行查询了:
$stmt->execute() or die( $stmt->error );
我已经测试了这段代码,它有效。
主要问题出在is_null( $val )
:使用数组,我不能用isset
作为测试,因为数组的每个元素都是偶数集。如果所有带有允许 Null 值的占位符的字段都具有 Null 广告默认值,则该代码有效。
我有同样的问题,所以我将这个答案 改编为 php 准备好的陈述:
if(!($stmt = $this->conn->prepare("INSERT INTO mytable (myfield) VALUES (IFNULL(?,DEFAULT(myfield)))"))){
throw new Exception("Prepare failed: (" . $this->conn->errno . ") " . $this->conn->error);
}
if(!($stmt->bind_param("s",$myfield))) { //$myfield is a variable that can be null, if so the default value for such field will be inserted
throw new Exception("Bind_param failed: (" . $this->conn->errno . ") " . $this->conn->error);
}
if(!$stmt->execute()) {
throw new Exception("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
}
假设我有一个准备好的声明,如下所示:
$insertSql = "";
$insertSql .= "INSERT INTO table";
$insertSql .= "(tag,month_interval,month_interval_lastupdated,date_due,date_due_lastupdated,date_completion,date_completion_lastupdated,";
$insertSql .= "activeNotification,date_lastmodified) ";
$insertSql .= "VALUES (?,?,NOW(),?,NOW(),?,NOW(),?,NOW())";
但有时其中一些问号不会被设置。
我可以在准备好的语句中替换一个关键字来告诉 MySQL 插入默认值吗?
类似于:
if($stmt = $mysqli->prepare($insertSql)) {
if(!isset($tag)) {
// code to find first question mark and replace w/ default value
}
$stmt->bind_param('sisss',$tag,$month_interval,$date_due,$date_completion);
$stmt->execute();
}
日期字段的默认值为“1000-01-01 00:00:00”,month_interval 的默认值为 0,其余字段的默认值为 NULL。
想一想,如果您遇到不知道所有值的情况,您应该准备语句甚至不要添加这些值。
同样在一些情况下(例如在自动增量字段上)你可以插入一个NULL
这将触发要插入的默认值,BUT 如果字段定义允许 NULL's
插入 NULL
,请务必小心NULL
.
在我看来,你的问题涉及一个有趣的主题。
通过快速搜索,我没有找到任何预定义的解决方案,但我会在接下来的几天继续搜索。
我有一个详细的解决方案,但它有点扭曲而且不完全干净。
首先,我用占位符重新定义查询:
$query = "
INSERT INTO table
(
tag,
month_interval,
month_interval_lastupdated,
date_due,
date_due_lastupdated,
date_completion,
date_completion_lastupdated,
activeNotification,
date_lastmodified
)
VALUES (<tag>,<month_interval>,NOW(),<date_due>,NOW(),<date_completion>,NOW(),<activeNotification>,NOW())
";
在这个例子中,我使用 <>
来包围占位符,但您可以选择您喜欢的占位符,确保它们不会与查询的其他元素混淆。
然后,我初始化一个关联数组,其中键作为占位符名称和要绑定的值,以及一个具有完整绑定类型集的变量 ($types
):
$values = array( 'tag'=>$tag, 'month_interval'=>$month_interval, 'date_due'=>$date_due, 'date_completion'=>$date_completion, 'activeNotification'=>$activeNotification );
$types = 'sisss';
然后,最重要的一行。我以这种奇怪的方式初始化一个数组:
$bind = array( Null, '' );
索引 0 设置为 Null
,因为它是为 stmt
对象(下面创建的)保留的;索引 1 是一个空字符串,将填充必要的绑定类型。
现在我对数组 $values
:
foreach
循环
$i = 0;
foreach( $values as $key => $val )
{
if( is_null( $val ) )
{
$query = str_replace( '<'.$key.'>', 'DEFAULT', $query );
}
else
{
$query = str_replace( '<'.$key.'>', '?', $query );
$bind[1] .= $types[$i];
$bind[] = &$val;
}
$i++;
}
在该循环中,如果值为 null,我将相应查询的占位符替换为 mySQL 关键字 DEFAULT
。否则,我用 ?
替换占位符,将相应的 $types
子字符串添加到 $bind[1]
,并将值(通过引用)附加到 $bind
数组。
至此,真正的查询已经准备就绪,我可以准备了:
$stmt = $db->prepare( $query ) or die( $stmt->error );
并且,如果没有默认值(count($bind)>2
),我可以绑定它:
if( count($bind)>2 )
{
$bind[0] = $stmt;
call_user_func_array( 'mysqli_stmt_bind_param', $bind );
}
如前所述,我将$bind[0]
设置为->prepare
返回的stmt对象,然后我使用call_user_func_array
执行mysqli_stmt_bind_param
。我不能直接调用 ->bind_param
因为我有一个可变参数 number.
在这个古怪的过程结束后,我终于可以执行查询了:
$stmt->execute() or die( $stmt->error );
我已经测试了这段代码,它有效。
主要问题出在is_null( $val )
:使用数组,我不能用isset
作为测试,因为数组的每个元素都是偶数集。如果所有带有允许 Null 值的占位符的字段都具有 Null 广告默认值,则该代码有效。
我有同样的问题,所以我将这个答案 改编为 php 准备好的陈述:
if(!($stmt = $this->conn->prepare("INSERT INTO mytable (myfield) VALUES (IFNULL(?,DEFAULT(myfield)))"))){
throw new Exception("Prepare failed: (" . $this->conn->errno . ") " . $this->conn->error);
}
if(!($stmt->bind_param("s",$myfield))) { //$myfield is a variable that can be null, if so the default value for such field will be inserted
throw new Exception("Bind_param failed: (" . $this->conn->errno . ") " . $this->conn->error);
}
if(!$stmt->execute()) {
throw new Exception("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
}