PDO "ON DUPLICATE KEY UPDATE" prepared statement (PDO“在重复键更新”准备语句)
PDO "ON DUPLICATE KEY UPDATE" prepared statement (PDO“在重复键更新”准备语句)
这是我第一次根据这个帖子尝试使用预处理语句。到目前为止,我收到了错误消息SQLSTATE[HY000]: General error: 1 near "ON": syntax error
。以下是查询和try
块的代码:
$query = "INSERT INTO results2015_2016 ('id','ata','atc','atcommon','atn','ats','atsog','hta','htc','htcommon','htn','hts','htsog','bs','bsc','canationalbroadcasts','gcl','gcl1','gs','r1','usnationalbroadcasts') VALUES (':id',':ata',':atc',':atcommon',':atn',':ats',':atsog',':hta',':htc',':htcommon',':htn',':hts',':htsog',':bs',':bsc',':canationalbroadcasts',':gcl',':gcl1',':gs',':r1',':usNationalBroadcasts') ON DUPLICATE KEY UPDATE id= ':id2'"; try { $db = new PDO('db info'); $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $stmt = $db->prepare($query); $stmt->bindParam(':ata', $ata, PDO::PARAM_STR); $stmt->bindParam(':atc' , $atc , PDO::PARAM_STR); $stmt->bindParam(':atcommon', $atCommon , PDO::PARAM_STR); $stmt->bindParam(':atn', $atn , PDO::PARAM_STR); $stmt->bindParam(':ats', $ats , PDO::PARAM_INT); $stmt->bindParam(':atsog', $atsog , PDO::PARAM_INT); $stmt->bindParam(':hta', $hta , PDO::PARAM_STR); $stmt->bindParam(':htc', $htc , PDO::PARAM_STR); $stmt->bindParam(':htcommon', $htCommon , PDO::PARAM_STR); $stmt->bindParam(':htn', $htn , PDO::PARAM_STR); $stmt->bindParam(':hts', $hts , PDO::PARAM_INT); $stmt->bindParam(':htsog', $htsog , PDO::PARAM_INT); $stmt->bindParam(':bs', $bs , PDO::PARAM_STR); $stmt->bindParam(':bsc', $bsc , PDO::PARAM_STR); $stmt->bindParam(':canationalbroadcasts', $caNationalBroadcasts , PDO::PARAM_STR); $stmt->bindParam(':gcl', $glc , PDO::PARAM_BOOL); $stmt->bindParam(':gcl1', $glc1 , PDO::PARAM_BOOL); $stmt->bindParam(':gs', $gs , PDO::PARAM_INT); $stmt->bindParam(':r1', $r1 , PDO::PARAM_BOOL); $stmt->bindParam(':usnationalbroadcasts', $usNationalBroadcasts , PDO::PARAM_STR); $stmt->bindParam(':id', $idGame , PDO::PARAM_INT); $stmt->bindParam(':id2', $idGame , PDO::PARAM_INT); $stmt->execute(); } catch (Exception $e) { echo $e->getMessage(); exit; }
我在这个错误消息上找不到太多信息,也不知道它与我的情况有什么关系。这段代码在一个解析jsonp的循环中...如果需要,我可以发布整个代码。
PDO "ON DUPLICATE KEY UPDATE" prepared statement问题的出现原因是占位符在SQL语句中不应该被引用,同时需要注意字段名应该用反引号而不是单引号括起来(或者如果字段名不被视为保留字且不包含空格等,则可以不加任何括号)。解决方法是去掉占位符的引号,并用反引号括起字段名。
PDO是PHP的一个数据库扩展,提供了一种安全、高效地与数据库进行交互的方法。在使用PDO执行预处理语句时,可以使用"ON DUPLICATE KEY UPDATE"语法来处理重复键冲突的情况。这种语法可以在插入数据时,如果存在重复的键,则更新已存在的记录,而不是插入新的记录。
然而,在上面的代码中,出现了一些问题。首先,占位符在SQL语句中被引用了,这是不正确的。占位符应该以冒号开头,并且不需要被引用。其次,字段名被用单引号括起来,这也是不正确的。在SQL语句中,字段名应该用反引号括起来,以避免与保留字冲突。
为了解决这个问题,我们需要对代码进行修改。首先,去掉占位符的引号,使其正确地以冒号开头。然后,将字段名用反引号括起来,以确保其正确性。修改后的代码如下所示:
$query = "INSERT INTO results2015_2016 ( `id`, `ata`, `atc`, `atcommon`, `atn`, `ats`, `atsog`, `hta`, `htc`, `htcommon`, `htn`, `hts`, `htsog`, `bs`, `bsc`, `canationalbroadcasts`, `gcl`, `gcl1`, `gs`, `r1`, `usnationalbroadcasts` ) VALUES ( :id, :ata, :atc, :atcommon, :atn, :ats, :atsog, :hta, :htc, :htcommon, :htn, :hts, :htsog, :bs, :bsc, :canationalbroadcasts, :gcl, :gcl1, :gs, :r1, :usnationalbroadcasts ) ON DUPLICATE KEY UPDATE id = :id2";
通过这样的修改,PDO "ON DUPLICATE KEY UPDATE" prepared statement问题得以解决。现在,我们可以正确地使用PDO来执行预处理语句,并处理重复键冲突的情况。这样可以确保数据的安全性和一致性,同时提高数据库操作的效率。
当使用预处理语句时,不需要将参数放在任何引号中。引擎本身会处理这个问题。例如,上面的代码片段中的$query是一个插入语句,将参数:a、:b、:c和:d插入到表x的列a、b、c和d中。
然而,当使用PDO的"ON DUPLICATE KEY UPDATE"语法时,问题可能会出现。"ON DUPLICATE KEY UPDATE"语法用于在插入数据时,如果存在重复的唯一键(unique key),则更新已存在的行。例如:
$query = "INSERT INTO x(a,b,c,d) VALUES(:a, :b, :c, :d) ON DUPLICATE KEY UPDATE a=:a, b=:b, c=:c, d=:d";
在这种情况下,如果将参数放在引号中,将会导致语法错误。因为引擎会将参数的值作为字符串,而不是作为变量。这样,"ON DUPLICATE KEY UPDATE"语法将会尝试将字符串值赋给列,而不是更新已存在的行。
解决这个问题的方法是,在预处理语句中不要将参数放在引号中。引擎会自动处理参数的类型。例如,上面的代码片段可以这样修改:
$query = "INSERT INTO x(a,b,c,d) VALUES(:a, :b, :c, :d) ON DUPLICATE KEY UPDATE a=:a, b=:b, c=:c, d=:d"; $stmt = $pdo->prepare($query); $stmt->bindParam(':a', $a); $stmt->bindParam(':b', $b); $stmt->bindParam(':c', $c); $stmt->bindParam(':d', $d); $stmt->execute();
在这个修改后的代码中,我们使用bindParam方法将参数绑定到预处理语句中的占位符。这样,引擎将会正确地处理参数的类型,并执行"ON DUPLICATE KEY UPDATE"语法。