MySQL返回PDO占位符名称

时间:2014-03-08 06:49:38

标签: php mysql pdo sql-update

有一个[similar post][1],但没有解决方案。

以下代码导致包含占位符名称的MySQL查询:

    $the_image_itself = "abcde123def.jpg";
    $title = "A Book";
    $description = "Something to Read";
    $the_image_itself = "%".$the_image_itself;

    $stmt = $db->prepare("UPDATE nky_posts SET `post_title`=:title, `post_content`=:description WHERE `guid` LIKE :the_image_itself");

    $stmt->bindParam(':title', $title);
    $stmt->bindParam(':description', $description);
    $stmt->bindValue(':the_image_itself', $the_image_itself, PDO::PARAM_STR);
    $stmt->execute();
    $stmt->debugDumpParams();
    echo "<hr/>";
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $affected_rows = $stmt->rowCount();

结果如下:

 start SQL: [105] UPDATE nky_posts SET `post_title`=:title,
     `post_content`=:description     
     WHERE `guid` LIKE :the_image_itself 
     Params: 3 Key: 
     Name:     [6] 
     :title paramno=-1 
     name=[6] ":title" 
     is_param=1 param_type=2 
     Key: Name: [12] :description 
     paramno=-1 name=[12] ":description" 
     is_param=1 param_type=2 
     Key: Name: [17] :the_image_itself paramno=-1 
     name=[17] ":the_image_itself" 
     is_param=1 param_type=2 

这是对象调用:

try{
$db=new PDO('mysql:host=localhost;dbname=viewingr_ssdevwp;   charset=utf8',$db_username,$db_password);
} 
catch(PDOException $e){
echo 'Error connecting to MySQL!: '.$e->getMessage();
exit();
}

3 个答案:

答案 0 :(得分:1)

我不知道您在哪里得到debugDumpParams()将显示原始SQL查询的印象 - 它不会。使用参数化查询时,在数据库中创建预准备语句,然后发送参数值单独。它们不会一起发送,这意味着无法打印原始SQL查询。

debugDumpParams()只会显示参数列表,名称,类型等,但其值。但是,您可以做的一件事是检查MySQL查询日志以查看已执行的原始SQL查询。

找到日志后,您可以使用以下命令查看最近执行的查询(前提是您具有SSH访问权限):

$ sudo tail -f /usr/local/mysql/data/yourQueryLog.log

以上路径只是一个例子。您系统上的实际路径可能有所不同。

答案 1 :(得分:1)

嗯,“答案”贴在下面,但真正的答案是,我应该停止对这个问题大打折扣,并在以后再回来,这对我来说似乎是最困难的事情之一去做。在我痴迷的某一点上,我发现了一个神秘的<br/>,后面是一个占位符值中的空格。我最后对变量执行substr($var, 0, -6)以删除异常,直到注意到我无意中将<br/>连接到填充变量的行的末尾; .<br/> - 可能在删除一行输出代码进行测试时。

我正在使用hostMonster技术支持尝试访问MySQL日志,因为人们说这是唯一可以找到MySQL使用占位符时“看到”的地方,但他们不记录MySQL查询,因为该文件将在terrabytes中。

凌晨3点或4点,我放弃了。

今天回头看了一眼,并通过以下步骤确认每项工作:

  1. 创建一个没有WHERE或占位符的简单 SELECT语句:

    $sql = "SELECT * FROM nky_posts";
    
  2. 使用“=”(不是LIKE)添加一个WHERE子句,变量是我知道的在DB中的文字:

    $the_image = "image_url_from_phpMyAdmin";
    $sql = "SELECT post_title FROM nky_posts WHERE guid = $the_image";
    
  3. 使用包含已知值的单个占位符替换文字变量:

    $the_image = "image_url_from_phpMyAdmin";
    
    $stmt->bindParam(':the_image', $the_image, PDO::PARAM_STR);
    
    $sql = "SELECT post_title FROM nky_posts WHERE guid = :the_image";
    
  4. 添加LIKE而不是=(记住将占位符变量与“%”连接起来)

    $the_image = "%" . $the_image . "%";
    
    $stmt->bindParam(':the_image', $the_image, PDO::PARAM_STR);
    
    $sql = "SELECT post_title FROM nky_posts WHERE guid LIKE :the_image_itself";
    
  5. 将“known”变量替换为动态变量(在本例中为XML结果):

    basename($oBookNode->getElementsByTagName('actual-link')->item(0)->nodeValue);
    

    (使用basename()函数只返回wordpress数据库中URL字符串的图像名称)

  6. 最后用我的UPDATE语句替换SELECT语句,添加两个额外的占位符来保存要插入的变量。最终代码:

    $sql = "UPDATE nky_posts SET post_title=:title, post_content=:description WHERE guid LIKE :the_image";
    
    $stmt = $db->prepare($sql);
    
    //foreach loop begins here
    foreach ($oDOM->getElementsByTagName('item') as $oBookNode)
    {
    
    $the_image = basename($oBookNode->getElementsByTagName('actual-link')->item(0)->nodeValue);
    
    $title = $oBookNode->getElementsByTagName('title')->item(0)->nodeValue;
    
    $description = $oBookNode->getElementsByTagName('actual-content')->item(0)->nodeValue;
    
    //concat % to variable for LIKE clause (probably only needed first one in this case, but...)
    
    $the_image = "%" . $the_image . "%";
    
    
    $stmt->bindParam(':title', $title, PDO::PARAM_STR);
    
    $stmt->bindParam(':description', $description, PDO::PARAM_STR);
    
    $stmt->bindParam(':the_image_itself', $another_image_itself, PDO::PARAM_STR);
    
    $stmt->execute();
    //end foreach loop
    }
    

    感谢大家的帮助。

答案 2 :(得分:0)

debugDumpParams函数调用的输出看起来正确。

debugDumpParams函数不显示绑定参数的值;它只显示SQL文本以及占位符名称/位置及其各自的数据类型。

我不确定我理解你提出的问题。


不需要在stmt上调用fetchAll方法,因为它是UPDATE语句。

请注意,对于rowCount,MySQL返回语句实际更改的行数,而不是匹配的行数。也就是说,如果设置的列中的值已经设置为指定值,那么MySQL不会“计算”该行受影响。