动态准备插入语句
dynamic prepared insert statement
先说一下,我刚开始学习准备好的语句,所以很多东西可能很难掌握,但我想尝试一下。
我正在尝试在我的 DatabaseObject class 中创建一个动态创建函数。该函数将采用可能任意数量的不同允许数据类型的任意数量的值。不幸的是,我尝试过的任何事情都没有奏效。这是代码。
public function create() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
//array of escaped values of all types in the object
$attributes = $this->sanitized_attributes();
$check = $mysqli->stmt_init();
$paramType = array();
$types = ''; $bindParam = array(); $where = ''; $count = 0;
foreach($attributes as $key=>$val)
{
$types .= 'i';
$bindParam[] = '$p'.$count.'=$param["'.$key.'"]';
$where .= "$key = ? AND ";
$count++;
}
$sql_query = "INSERT INTO `".static::$table_name."` ";
$sql_query .= "VALUES (";
foreach ($attributes as $key => $value) {
$valueType = gettype($value);
if ($valueType == 'string') {
$sql_query .= "?,";
array_push($paramType, "s");
} else if ($valueType == 'integer') {
$sql_query .= "?,";
array_push($paramType, "i");
} else if ($valueType == 'double') {
$sql_query .= "?,";
array_push($paramType, "d");
} else {
$sql_query .= "?,";
array_push($paramType, "b");
}
}
$sql_query .= ")";
}
此时我完全不知道我应该做什么。
我已经得到了简单的准备好的语句来工作,但是这个要复杂得多和动态得多,我不知道我是否正确地处理了到目前为止的过程以及在 sql_query 之后该怎么做为了让它发挥作用。这里的所有问题都让我感到困惑,所以也许如果我得到有关我当前代码的指导以查看我哪里出错了,它会有所帮助。
非常感谢你的宝贵时间。
public function create() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
$attributes = $this->sanitized_attributes();
$tableName = static::$table_name;
$columnNames = array();
$placeHolders = array();
$values = array();
foreach($attributes as $key=>$val)
{
// skip identity field
if ($key == static::$identity)
continue;
$columnNames[] = '`' . $key. '`';
$placeHolders[] = '?';
$values[] = $val;
}
$sql = "Insert into `{$tableName}` (" . join(',', $columnNames) . ") VALUES (" . join(',', $placeHolders) . ")";
$statement = $mysqli->stmt_init();
if (!$statement->prepare($sql)) {
die("Error message: " . $mysqli->error);
return;
}
$bindString = array();
$bindValues = array();
// build bind mapping (ssdib) as an array
foreach($values as $value) {
$valueType = gettype($value);
if ($valueType == 'string') {
$bindString[] = 's';
} else if ($valueType == 'integer') {
$bindString[] = 'i';
} else if ($valueType == 'double') {
$bindString[] = 'd';
} else {
$bindString[] = 'b';
}
$bindValues[] = $value;
}
// prepend the bind mapping (ssdib) to the beginning of the array
array_unshift($bindValues, join('', $bindString));
// convert the array to an array of references
$bindReferences = array();
foreach($bindValues as $k => $v) {
$bindReferences[$k] = &$bindValues[$k];
}
// call the bind_param function passing the array of referenced values
call_user_func_array(array($statement, "bind_param"), $bindReferences);
$statement->execute();
$statement->close();
return true;
}
我想特别说明一下,我自己没有找到解决办法。我有很长一段时间的开发人员找到了这个解决方案,并想post它给那些可能想知道的人。
我无意中找到了你的旧 post,因为我正在努力寻找完全相同问题的解决方案。我的代码似乎更有优势,因为只包含一个循环。因此,我会将其添加为对此 post:
的可能改进
$sqlquery = $this->MySQLiObj->prepare($dummy);
$paramQuery = array();
$paramQuery[0] = '';
$n = count($valueArray);
for($i = 0; $i < $n; $i++) {
$checkedDataType = $this->returnDataType($valueArray[$i]);
if($checkedkDataType==false) {
return false;
}
$paramQuery[0] .= $checkedDataType;
/* with call_user_func_array, array params must be passed by reference -> & */
$paramQuery[] = &$valueArray[$i];
}
/*In array(): sqlquery(object)->bind_param(method)*/
call_user_func_array(array($sqlquery, 'bind_param'), $paramQuery);
$sqlquery->execute();
/*Can be used identical to $result = $mysqli->query()*/
$result = $this->MySQLiObj->get_result();
$sqlquery->close();
使用函数 returnDataType() 和 switch 语句,如果对特定数据类型有偏好,这可能会更快。
private function returnDataType($input) {
switch(gettype($input)) {
case string: return 's';
case double: return 'd';
case integer: return 'i';
default: $this->LOG->doLog("Unknown datatype during database access."); return 's';
}
}
先说一下,我刚开始学习准备好的语句,所以很多东西可能很难掌握,但我想尝试一下。
我正在尝试在我的 DatabaseObject class 中创建一个动态创建函数。该函数将采用可能任意数量的不同允许数据类型的任意数量的值。不幸的是,我尝试过的任何事情都没有奏效。这是代码。
public function create() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
//array of escaped values of all types in the object
$attributes = $this->sanitized_attributes();
$check = $mysqli->stmt_init();
$paramType = array();
$types = ''; $bindParam = array(); $where = ''; $count = 0;
foreach($attributes as $key=>$val)
{
$types .= 'i';
$bindParam[] = '$p'.$count.'=$param["'.$key.'"]';
$where .= "$key = ? AND ";
$count++;
}
$sql_query = "INSERT INTO `".static::$table_name."` ";
$sql_query .= "VALUES (";
foreach ($attributes as $key => $value) {
$valueType = gettype($value);
if ($valueType == 'string') {
$sql_query .= "?,";
array_push($paramType, "s");
} else if ($valueType == 'integer') {
$sql_query .= "?,";
array_push($paramType, "i");
} else if ($valueType == 'double') {
$sql_query .= "?,";
array_push($paramType, "d");
} else {
$sql_query .= "?,";
array_push($paramType, "b");
}
}
$sql_query .= ")";
}
此时我完全不知道我应该做什么。
我已经得到了简单的准备好的语句来工作,但是这个要复杂得多和动态得多,我不知道我是否正确地处理了到目前为止的过程以及在 sql_query 之后该怎么做为了让它发挥作用。这里的所有问题都让我感到困惑,所以也许如果我得到有关我当前代码的指导以查看我哪里出错了,它会有所帮助。
非常感谢你的宝贵时间。
public function create() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
$attributes = $this->sanitized_attributes();
$tableName = static::$table_name;
$columnNames = array();
$placeHolders = array();
$values = array();
foreach($attributes as $key=>$val)
{
// skip identity field
if ($key == static::$identity)
continue;
$columnNames[] = '`' . $key. '`';
$placeHolders[] = '?';
$values[] = $val;
}
$sql = "Insert into `{$tableName}` (" . join(',', $columnNames) . ") VALUES (" . join(',', $placeHolders) . ")";
$statement = $mysqli->stmt_init();
if (!$statement->prepare($sql)) {
die("Error message: " . $mysqli->error);
return;
}
$bindString = array();
$bindValues = array();
// build bind mapping (ssdib) as an array
foreach($values as $value) {
$valueType = gettype($value);
if ($valueType == 'string') {
$bindString[] = 's';
} else if ($valueType == 'integer') {
$bindString[] = 'i';
} else if ($valueType == 'double') {
$bindString[] = 'd';
} else {
$bindString[] = 'b';
}
$bindValues[] = $value;
}
// prepend the bind mapping (ssdib) to the beginning of the array
array_unshift($bindValues, join('', $bindString));
// convert the array to an array of references
$bindReferences = array();
foreach($bindValues as $k => $v) {
$bindReferences[$k] = &$bindValues[$k];
}
// call the bind_param function passing the array of referenced values
call_user_func_array(array($statement, "bind_param"), $bindReferences);
$statement->execute();
$statement->close();
return true;
}
我想特别说明一下,我自己没有找到解决办法。我有很长一段时间的开发人员找到了这个解决方案,并想post它给那些可能想知道的人。
我无意中找到了你的旧 post,因为我正在努力寻找完全相同问题的解决方案。我的代码似乎更有优势,因为只包含一个循环。因此,我会将其添加为对此 post:
的可能改进 $sqlquery = $this->MySQLiObj->prepare($dummy);
$paramQuery = array();
$paramQuery[0] = '';
$n = count($valueArray);
for($i = 0; $i < $n; $i++) {
$checkedDataType = $this->returnDataType($valueArray[$i]);
if($checkedkDataType==false) {
return false;
}
$paramQuery[0] .= $checkedDataType;
/* with call_user_func_array, array params must be passed by reference -> & */
$paramQuery[] = &$valueArray[$i];
}
/*In array(): sqlquery(object)->bind_param(method)*/
call_user_func_array(array($sqlquery, 'bind_param'), $paramQuery);
$sqlquery->execute();
/*Can be used identical to $result = $mysqli->query()*/
$result = $this->MySQLiObj->get_result();
$sqlquery->close();
使用函数 returnDataType() 和 switch 语句,如果对特定数据类型有偏好,这可能会更快。
private function returnDataType($input) {
switch(gettype($input)) {
case string: return 's';
case double: return 'd';
case integer: return 'i';
default: $this->LOG->doLog("Unknown datatype during database access."); return 's';
}
}