PDO更新声明不起作用

时间:2017-09-06 14:42:27

标签: php mysql pdo

我对PDO声明有问题"更新"。我想使用以下代码更新数据库中的现有列:

<?php
$sql="UPDATE $title SET header = $header;";

for($co=1,$arr=0;$co<=$count;$co++,$arr++)
{
   $sql .= "UPDATE $title SET theme$co = :theme, content$co = :content;";
   $insert = array('theme' => $theme[$arr], 'content' => $content[$arr]); 

   $statement = $pdo->prepare($sql);
   $statement->execute($insert);
}
?>

问题是,当完成此代码时,数据库中没有任何事情发生。 阵列&#34;主题&#34; &安培; &#34;内容&#34;只包含一些用户已写入其中的文本。根据用户输入的主题/内容的数量,您获得的阵列越多。例如:

$theme1="a";
$theme2="b";
$content1="abc";
$content2="def";

因此在数据库中,已经创建了与主题相同名称的列。内容数组。现在我想要做的是,将例如$ theme1的值插入到列#34; theme1&#34;与$ content1相同的事情&#34; content1&#34;等等...

我已经尝试过更改

$sql .= to $sql =

并将其作为单个查询执行。但那也没有用。

我没有使用&#34; Insert&#34;声明,因为它总是在数据库中创建一个新行,所以它看起来像this 正如您在屏幕截图中看到的那样,这是完全错误的,我试图将所有内容都放在一行中。这就是我尝试更新而不是插入的原因。 由于表格及其所有列的创建与PDO一起工作正常,我想知道为什么Update根本不起作用。

编辑:变量&#34; titel&#34;没有拼错,我是德国人,这对我来说是对的。由于您可以根据需要命名变量,因此我可以用母语进行操作。但是,无论如何,谢谢告诉我,我试图用英语单词替换所有德语变量,但我错过了那个,所以我现在改变了。

1 个答案:

答案 0 :(得分:0)

这是我的解决方案。它包含错误报告/显示以及将PDO预处理语句与exception handling结合使用所涉及的所有适当步骤。

代码已注释。

尝试使用sprintf function来适应自己。有了它,您可以以优雅的方式构建非常复杂的sql语句。

祝你好运!

<?php

/*
 * ============================================================
 * Set error reporting level and display errors on screen.
 * Use it ONLY ON A DEVELOPMENT SYSTEM, NEVER ON PRODUCTION!
 * If you activate it on a live system, then the users will see
 * all the errors of your system. And you don't want this!
 * ============================================================
 */
error_reporting(E_ALL);
ini_set('display_errors', 1);

/*
 * User variables.
 */

// "table name" not "title" ;-)
$tableName = 'your_table';

// "Themes" not "theme" ;-)
$themes = array('t1', 't2', 't3', 't4', 't5');

// "Contents" not "content" ;-)
$contents = array('c1', 'c2', 'c3', 'c4', 'c5');

// Counter for building the sql statement's assignment list
// and the input parameters list for the sql statement's markers.
$count = 5;

try {
    /*
     * Create a PDO instance as db connection to a MySQL db.
     */
    $connection = new PDO(
            'mysql:host=localhost;port=3306;dbname=yourDb;charset=utf8'
            , 'yourDbUsername'
            , 'yourDbPassword'
    );

    /*
     * Assign the driver options to the db connection.
     */
    $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    $connection->setAttribute(PDO::ATTR_PERSISTENT, TRUE);

    /*
     * Build the sql statement and fill the input parameters list.
     * 
     * ------------------------------------------------------------------------
     * Notes:
     * 
     *  - Quote: "You cannot use a named parameter marker of the same name more 
     *    than once in a prepared statement, unless emulation mode is on."
     *    See: http://php.net/manual/de/pdo.prepare.php
     * 
     *  - DON'T use semicolon at the end of sql statements in PHP!
     * ------------------------------------------------------------------------
     */
    // Sql statement's assignment list. Array of "column-name = :column-marker, ..." assignments.
    $assignments = array();

    // Input parameters list, e.g the values for the sql statement markers.
    $bindings = array();

    // Note: Use one iteration variable for both operations!
    for ($i = 1; $i <= $count; $i++) {
        // Add sql assignments to assignment list.
        $assignments[] = sprintf('theme%s = :theme%s, content%s = :content%s', $i, $i, $i, $i);

        // Add corresponding input parameter values to bindings list.
        $bindings[':theme' . $i] = $themes[$i - 1];
        $bindings[':content' . $i] = $contents[$i - 1];
    }

    // Final sql statement.
    $sql = sprintf(
            'UPDATE %s 
            SET header = %s
            %s'
            , $tableName
            , $header
            , $assignments ? ',' . implode(',', $assignments) : ''
    );

    /*
     * Prepare and validate the sql statement.
     * 
     * --------------------------------------------------------------------------------
     * If the database server cannot successfully prepare the statement, PDO::prepare() 
     * returns FALSE or emits PDOException (depending on error handling settings).
     * --------------------------------------------------------------------------------
     */
    $statement = $connection->prepare($sql);

    if (!$statement) {
        throw new UnexpectedValueException('The sql statement could not be prepared!');
    }

    /*
     * Bind the input parameters to the prepared statement.
     * 
     * -----------------------------------------------------------------------------------
     * Unlike PDOStatement::bindValue(), when using PDOStatement::bindParam() the variable 
     * is bound as a reference and will only be evaluated at the time that 
     * PDOStatement::execute() is called.
     * -----------------------------------------------------------------------------------
     */
    foreach ($bindings as $key => $value) {
        // Get the name of the input parameter by its key in the bindings array.
        $inputParameterName = is_int($key) ? ($key + 1) : (':' . ltrim($key, ':'));

        // Get the PDO::PARAM_* constant, e.g the data type of the input parameter, by its value.
        $inputParameterDataType = PDO::PARAM_STR;
        if (is_int($value)) {
            $inputParameterDataType = PDO::PARAM_INT;
        } elseif (is_bool($value)) {
            $inputParameterDataType = PDO::PARAM_BOOL;
        }

        // Bind the input parameter.
        $bound = $statement->bindValue($inputParameterName, $value, $inputParameterDataType);

        if (!$bound) {
            throw new UnexpectedValueException('An input parameter can not be bound!');
        }
    }

    /*
     * Execute the prepared statement.
     * 
     * ------------------------------------------------------------------
     * PDOStatement::execute returns TRUE on success or FALSE on failure.
     * ------------------------------------------------------------------
     */
    $executed = $statement->execute();

    if (!$executed) {
        throw new UnexpectedValueException('The prepared statement can not be executed!');
    }

    /*
     * Get number of affected rows.
     */
    $numberOfAffectedRows = $statement->rowCount();

    /*
     * Display results.
     */
    echo $numberOfAffectedRows;

    /*
     * Close connection.
     */
    $connection = NULL;
} catch (PDOException $exc) {
    echo $exc->getMessage();
    // Log the whole exception object to a file.
    // $logger->log($exc);
    exit();
} catch (Exception $exc) {
    echo $exc->getMessage();
    // Log the whole exception object to a file.
    // $logger->log($exc);
    exit();
}

如果您愿意,请参阅我的答案here(&#34;编辑&#34;部分),我在其中发布了数据库适配器类。它负责处理所有数据库操作,验证和异常处理案例。