我的问题是我无法让占位符在我的SQL语句中工作。具体来说,在下面的代码中,当我用类似':tripsid'
的值替换占位符'abcdefg'
时,未按预期创建TABLE。
SQL错误是:
PDO :: errorInfo():数组([0] => 42000 [1] => 1064 [2] =>你有一个 SQL语法错误;查看与您的手册相对应的手册 MySQL服务器版本,用于在*''sdfghjk'附近使用正确的语法(id INT NOT NULL,stop_start SMALLINT NOT NULL,stop_end SMA'* at line 1)
代码:
// My method to create a table with PDO and placeholders
public function routes_table() {
$this->connect();
$STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS :tripsid (
id INT NOT NULL,
stop_start SMALLINT NOT NULL,
stop_end SMALLINT NOT NULL,
distance SMALLINT NOT NULL,
duration TINYINT NOT NULL,
medium TINYTEXT NOT NULL,
CONSTRAINT pk_routes PRIMARY KEY ( id )
)');
$tripsid = "sdfghjk";
$STH->bindParam(':tripsid', $tripsid, PDO::PARAM_STR, 7);
$STH->execute();
// SQL Errors
if (!$STH->execute($input)) {
echo "\nPDO::errorInfo():\n";
print_r($STH->errorInfo());
}
$this->disconnect();
}
我已经尝试了我能想到的一切。有没有人看到这个错误?
答案 0 :(得分:0)
现在我知道PDO :: bindParam()自动绑定到参数的引号导致问题。有没有人知道如何从表名中删除引号所以我的代码将是......
$STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS tablename (
id INT NOT NULL,...
而不是
$STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS 'tablename' (
id INT NOT NULL,
答案 1 :(得分:0)
我看到这个问题已经过了一年多了,但我偶然发现了它并想突出显示一些内容:这与引号无关。
当出现错误并且您获得与相关语法相关的SQL片段时,它会自动包含在一对单引号周围。这通常会使它看起来好像有一个不同的问题,即双引号和单引号混合的问题。
在这个例子中 -
PDO :: errorInfo():数组([0] => 42000 1 => 1064 [2] =>您的SQL语法出错; 检查与MySQL服务器版本对应的手册,以便在'sdfghjk'附近使用正确的语法(id INT NOT NULL,stop_start SMALLINT NOT NULL,stop_end SMA'在第1行)
指的是:
'sdfghjk' ( id INT NOT NULL, stop_start SMALLINT NOT NULL, stop_end SMA
最外面的引号只是特定于错误输出;像我一样 - 我担心你注意到这一点,并认为你的错误是关于错误的引号。 这是一个红色的鲱鱼!删除最外面的单引号,以实际看到不正确的SQL。
至于您的真实问题:您不能将表名(或列名)指定为参数;这在大多数平台和API的准备语句中很常见。这适用于任何查询 - 选择/插入/更新等等 - 它们都不能接受表名作为参数。有关详细信息,请参阅此question here。
因此,考虑到这一点,我会使用sprintf()
来实现这样的目标......
$STH = $this->DBH->prepare(
sprintf('CREATE TABLE IF NOT EXISTS %s (
id INT NOT NULL,
stop_start SMALLINT NOT NULL,
stop_end SMALLINT NOT NULL,
distance SMALLINT NOT NULL,
duration TINYINT NOT NULL,
medium TINYTEXT NOT NULL,
CONSTRAINT pk_routes PRIMARY KEY ( id )
)', $tripsid)
);
$STH->execute();
是的,当你仍然需要操作字符串时,它更需要PDO的美感 - 不幸的是,这是使用表名作为参数的情况! 此外,请记住,这意味着“旧样式”SQL注入风险仍然可以应用,因为您直接操作查询。
我不认为这会在一年后帮助OP,但我希望它现在能帮助别人! :)