php bindvalue insert,关于postgresql:PHP-bindValue()的PDO问题

李兴为
2023-12-01

我正在编写一个类,该类以编程方式创建给定某些列名称的表。 我正在使用PDO准备好的语句,这似乎引起了一些问题。

基本步骤如下:

// create a query string to be sent to $pdo->prepare

$sql =

'CREATE TEMP TABLE :tmp_table_name (

:person_id bigint,

:encntr_id bigint,

:prsnl_id bigint,

:program_detail text,

:program_name text

);';

$stmt = $pdo->prepare($sql);

// Bind table name

$stmt->bindValue(':tmp_table_name', 'tmp_patients', PDO::PARAM_STR);

// Bind column names

$columnNames = [

'person_id',

'encnt_id',

'prsnl_id',

'program_detail',

'program_name',

];

foreach($columnNames as $name) {

$stmt->bindValue(':'.$name, $name, PDO::PARAM_STR);

}

$ret = $stmt->execute();

// $ret is false! The statement fails.

这是$stmt->errorInfo()[2]显示的内容:

ERROR:  syntax error at or near"$1"

LINE 1: CREATE TEMP TABLE $1 ($2 bigint,

$3 bigint,

$4 bigint,

$5 text,

$6 te...

为什么$ 1,$ 2,$ 3等在查询中显示? 关于如何进一步调试此PDO语句,您有什么提示吗?

更新资料

我正在尝试一种不同的方法,不使用bindParam,而是将一组参数传递给$ stmt-> execute()。 我仍然遇到相同的错误,但是...

$stmt = $this->pdo->prepare($this->createSql);

$keys = [];

// Bind column names

foreach($this->columnNames as $name) {

$keys[] = ':'.$name;

}

$params = array_combine($keys, $this->columnNames);

// Bind table name

$params[':tmp_table_name'] = 'tmp_'.$this->objName;

$ret = $stmt->execute($params);

if (!$ret) {

throw new Exception('execSchema() failed! '. $stmt->errorInfo()[2]);

}

为什么用bindValue代替bindParam? php.net/manual/es/pdostatement.bindparam.php

@ONe,因为bindValue更灵活(我可以将字符串用作具有bindValue的值。bindParam要求该值是变量。)stackoverflow.com/questions/1179874/

请记住,您还可以发送参数以执行($ params)php.net/manual/es/pdostatement.execute.php

在我看来,好像您要绑定到表名/列一样,您不能使用PDO来做-您只能将值绑定到占位符。

如您的代码所示:

// Bind table name

$stmt->bindValue(':tmp_table_name', 'tmp_patients', PDO::PARAM_STR);

感觉好像它应该工作,但是没有。

例如,这将不起作用:

$sql ="insert into mytable (:thing1) values (:thing2);

$stmt->bindValue(':thing1', 'column_name' ); // this would not

$stmt->bindValue(':thing2', 'column_value' ); // this would have (on its own)

但是,类似这样的方法将起作用,它应该提供您的解决方案或类似的结果:

// imagine an incoming POST load like this:

$cols = ['fname','lname'];

$array_cnt = count($cols);  // 2

$sql = 'INSERT INTO mytable ('.join(',', $cols).') ';

// and then that number of placeholders used

$sql .= 'VALUES (' . join( array_fill( 0, $array_cnt, '?' ), ', ' ) . ')';

echo $sql;

感谢您的明确答复。 我没有意识到您无法在PDO中绑定表名/列,但我对此表示怀疑。 以前,我按照您的建议进行操作,但是我担心SQL注入攻击,因此我认为应该使用准备好的语句来执行此操作。

bindParam()和bindValue()通过值引用来处理值,这意味着您将其传递给$value变量的引用,而不是调用它时的值。 当循环结束并调用query()时,$value将等于$array中的最后一个。

使用对数组中项目的引用:

$stmt->bindValue(":".$array[$param], $array[$param]);

$stmt->bindParam($param, $array[$param]);

香港专业教育学院重写这样的循环:foreach($columnNames as $k => $name) { $stmt->bindValue(:.$columnNames[$k], $columnNames[$k]); }但我仍然收到相同的错误。

 类似资料: