出于某种原因,我在尝试使用mysqli
mysqli_stmt :: bind_result():绑定变量数不匹配 准备好的陈述中的字段数
这个db类工作正常,直到我尝试使用LEFT OUTER JOIN
我想知道是否有人知道为什么?我将在下面发布查询,架构等。
注意:我在这里看到一个问题,建议我专门拼出我想要选择的所有字段名称,而不是使用'*'(星号)。涉及很多领域,我花了将近一个小时的时间将它们全部输入。当我测试时,它没有改变任何东西。我已经省略了它并返回使用star,以防万一有人建议我把它们全部输出。已经尝试过了。没有帮助。
另外:如果我把它直接放到phpMyAdmin中,这个查询工作正常,所以这是一个有效的查询。在尝试由于某种原因绑定结果时抛出错误。即使我删除了多个连接并且只有一个左连接,它仍然会抛出关于没有正确的参数计数的错误。我不明白。
SELECT * FROM `SlipMaster`
left outer join `SlipMain`
on `SlipMaster`.`slipCode` = `SlipMain`.`slipCode`
left outer join `ContractMain`
on `SlipMain`.`slipContractId` = `ContractMain`.`id`
left outer join `ClientMain`
on `SlipMain`.`slipClientId` = `ClientMain`.`id`
left outer join `PaymentMain`
on `ContractMain`.`contractPaymentId` = `PaymentMain`.`id`
left outer join `VesselMain`
on `SlipMain`.`slipVesselId` = `VesselMain`.`id`
WHERE 1 = ?
$from = '
`SlipMaster`
left outer join `SlipMain`
on `SlipMaster`.`slipCode` = `SlipMain`.`slipCode`
left outer join `ContractMain`
on `SlipMain`.`slipContractId` = `ContractMain`.`id`
left outer join `ClientMain`
on `SlipMain`.`slipClientId` = `ClientMain`.`id`
left outer join `PaymentMain`
on `ContractMain`.`contractPaymentId` = `PaymentMain`.`id`
left outer join `VesselMain`
on `SlipMain`.`slipVesselId` = `VesselMain`.`id`';
$dbi->new_query();
$dbi->add_param('i', '1');
$dbi->select($from, '*', '1=?');
<?php
class mysqliObject {
public $user = "";
public $pass = "";
public $name = "";
public $host = "";
public $_db;
public $_config;
public $MYSQLI_LINK = FALSE;
public $rows = FALSE;
public $last_error = FALSE;
public $last_query = FALSE;
public $result = FALSE;
public $last_id = FALSE;
public $paramTypeArray = [];
public $paramBindArray = [];
public function __construct() {
}
public function __destruct() {
$this->close();
}
public function connect() {
$this->host = $this->_config->get('DBHOST');
$this->name = $this->_config->get('DBNAME');
$this->user = $this->_config->get('DBUSER');
$this->pass = $this->_config->get('DBPASS');
$this->MYSQLI_LINK = new mysqli($this->host, $this->user, $this->pass, $this->name);
}
public function setDatabase($databaseConnection) {
$this->_db = $databaseConnection;
}
public function setConfig($config) {
$this->_config = $config;
}
public function close() {
@mysqli_close($this->MYSQLI_LINK);
}
public function get_hash($p) {
return password_hash($p, PASSWORD_BCRYPT, array("cost" => 10));
}
public function check_password($p, $h) {
return (password_verify($p, $h)) ? true : false;
}
public function get_rndkey($length=32) {
$random_string="";
while(strlen($random_string)<$length && $length > 0) {
$randnum = mt_rand(0,61);
$random_string .= ($randnum < 10) ?
chr($randnum+48) : ($randnum < 36 ?
chr($randnum+55) : $randnum+61);
}
return $random_string;
}
public function escape($value) {
return mysqli_real_escape_string($this->MYSQLI_LINK, $value);
}
public function get_lastid() {
return $this->MYSQLI_LINK->insert_id;
}
public function new_query() {
$this->paramTypeArray = Array();
$this->paramBindArray = Array();
}
public function add_param($t, $d) {
$this->paramTypeArray[] = $t;
$this->paramBindArray[] = $d;
}
// Shortcut for Select Method
public function s($t,$x, $d, $w) {
$this->new_query();
foreach($d as $v) {
$this->add_param($v['t'], $v['v']);
}
return $this->select($t, $x, $w) ? $this->result : false;
}
public function select($t, $d, $c) {
/* Types: s = string, i = integer, d = double, b = blob */
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = 'SELECT '.$d.' FROM '.$t.' WHERE '.$c;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$meta = $s->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$fields[$var] = &$$var;
}
call_user_func_array(array($s,'bind_result'),$fields);
$i = 0;
while ($s->fetch()) {
$results[$i] = [];
foreach($fields as $k => $v) {
$results[$i][$k] = $v;
}
$i++;
}
$s->close();
$this->last_query = $q;
if (count($results) > 0) {
$this->result = $results;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
return FALSE;
}
public function delete($t, $c) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = "delete from ".$t." where ".$c;
$s = $this->MYSQLI_LINK->prepare($q);
$this->last_query = $q;
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
public function insert($t, $d) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$query_cols = 'insert into '.$t.' (';
$query_vals = 'values (';
while (list($key, $value) = each($d)) {
$query_cols .= $value . ', ';
$query_vals .= '?, ';
}
$query_cols = substr($query_cols, 0, strlen($query_cols) - 2);
$query_vals = substr($query_vals, 0, strlen($query_vals) - 2);
$q = $query_cols . ') ' . $query_vals . ')';
$this->last_query = $q;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$this->last_id = $s->insert_id;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
public function update($t, $d, $c) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = 'update ' . $t . ' set ';
while (list($key, $value) = each($d)) {
$q .= $value . ' = ?, ';
}
//strip comma off end of variable
$q = substr($q, 0, strlen($q) - 2);
$q .= ' where ' . $c;
$this->last_query = $q;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
} // End Class
注意:如果您需要我发布更完整的架构,请告诉我。这只显示链接连接的字段。所有字段都是INT(255)唯一,id
字段是INT(255)AI PRIMARY
SlipMaster
通过SlipMain
链接到slipCode
,所有其他链接都是外键
到小学id
SlipMaster (id, slipCode)
SlipMain (id, slipCode, slipContractId, slipClientId, slipVesselId)
ContractMain (id, contractPaymentId)
ClientMain (id)
PaymentMain (id)
VesselMain (id)
答案 0 :(得分:2)
*
是所有表中的所有字段JOINing
。这包括重复项,例如slipCode,至少存在两次。
计划A:拼出你真正想要的字段。这样可以更容易地计算它们并知道要“绑定”多少。并且它将清楚地说明绑定它们的顺序。
B计划:不要使用bind_result
;只需将结果提取到数组或散列中。
计划C:两者都做。 (我更喜欢这个。)
答案 1 :(得分:2)
@Notorious,我认为你的问题的答案不是sql,而是你正在使用的bind_result()
函数。
解释更进一步,bind_result()
函数用于将检索到的数据从数据库分配给变量。因此,选择的字段数(从数据库返回)必须等于绑定结果的数量。
例如, 如果我从数据库中选择了firstname和lastname字段,我必须使用
bind_result($firstname, $lastname);
因此,您可以看到bind_result()
中的变量数等于所选字段的数量。
对于您的情况,您正在选择从第一个db到第二个到第三个..blablabla的所有内容,直到最后一个db。因此,请确保分配给bind_result()
函数的字段数等于返回的所有字段的数量。这是所有数据库中总列数的总和。
所以你打算做很多打字,但至少要做到最好。
祝你好运,我希望它有所帮助。