Estoy teniendo un problema con PDO declaraciones Preparadas, donde si necesita utilizar el mismo aprieto variable varias veces, la consulta no validar.

Ejemplo:

$params = array (
    ':status' => $status,
    ':userid' => $_SESSION['userid']
);

$stmt = $pdo->prepare ('
    INSERT INTO 
        tableName
        ( userId, status )
        VALUES
        ( :userid, ":status" )
        ON DUPLICATE KEY UPDATE
            status = ":status"
');

if ( ! $stmt->execute ( $params ))
{
    print_r( $stmt->errorInfo ());
}

EDITAR: Los valores de la $params son:

Array ( [:status] => PAID [:userid] => 111 )

EDITAR 2:

Me he dado cuenta de que en lugar de los valores originales, en lugar de id de usuario, 0 se inserta, y en lugar de estado de una cadena vacía se inserta.

¿Y qué hace el errorInfo pantalla?
Usted puede volver a escribir la consulta como INSERT INTO tableName ( userId, status ) VALUES ( ?, "?" ) ON DUPLICATE KEY UPDATE status = "?" y su $params serán como: array($_SESSION['userid'], $status, $status). Y es interesante lo de la salida de errorInfo.
Pasa a la consulta con ningún error, pero inserta NULL para :situación y :userid.
Asegúrese de que $status y $_SESSION['userid'] no nulls
¿Su $params matriz que contenga los valores crees que tiene? var_dump ($params);

OriginalEl autor Kao | 2012-08-20

4 Comentarios

  1. 8

    Problema era las comillas alrededor de la :estado. Quita las comillas y todo es bueno.

    También ser conscientes de la sensibilidad a mayúsculas.
    Todavía no parece funcionar cuando PDO::ATTR_EMULATE_PREPARES es falso, no se puede encontrar ninguna documentación en la que

    OriginalEl autor Kao

  2. 3

    Su matriz de teclas no necesita contener un signo de dos puntos. El colon es puramente para PDO para saber que lo que sigue es el nombre de un parámetro.

    $params = array (
        ':status' => $status,
        ':userid' => $_SESSION['userid']
    );

    debe ser

    $params = array (
        'status' => $status,
        'userid' => $_SESSION['userid']
    );
    Maldita sea, tan tonta de pasar por alto que
    Sí, me di cuenta de que después de la publicación de mi comentario inicial. Es curioso cómo poco cosas como que no es tan fácil perderse.
    Lo he utilizado con el ‘:’ antes, con gran éxito. Esta es la única de las veces es no trabajar. También, de acuerdo a la documentación de PDO, lo utilizan con el :. También al hacer esto no va a ser capaz de diferir de un nombre de tabla o de una variable.
    Que raro, nunca se dieron cuenta de que en la documentación antes. Siempre he usado sin los dos puntos en la matriz de teclas y funciona bien. Supongo que en ese caso es volver a la pregunta original, ¿es la matriz que está pasando a ejecutar realmente mantener los valores crees que tiene?
    Editado el $params valores en la pregunta.

    OriginalEl autor GordonM

  3. 2

    Funciona muy bien para mí. E. g.

    <?php
    $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    setup($pdo);
    
    echo 'client version: ', $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), "\n";
    echo 'server version: ', $pdo->getAttribute(PDO::ATTR_SERVER_VERSION), "\n";
    echo "before:\n";
    foreach( $pdo->query('SELECT * FROM tmpTableName', PDO::FETCH_ASSOC) as $row ) {
        echo join(', ', $row), "\n";
    }
    
    $status = 1;
    $_SESSION['userid'] = 'foo';
    
    $params = array (
        'status' => $status,
        'userid' => $_SESSION['userid'],
    );
    
    $stmt = $pdo->prepare ('
        INSERT INTO 
            tmpTableName
            (userId, status)
        VALUES
            (:userid, :status)
        ON DUPLICATE KEY UPDATE
            status = :status
    ');
    
    if ( ! $stmt->execute ( $params ))
    {
        print_r( $stmt->errorInfo ());
    }
    
    echo "after:\n";
    foreach( $pdo->query('SELECT * FROM tmpTableName', PDO::FETCH_ASSOC) as $row ) {
        echo join(', ', $row), "\n";
    }
    
    function setup($pdo) {
        $pdo->exec('
            CREATE TEMPORARY TABLE tmpTableName (
                userId varchar(32),
                status int,
                unique key(userId)
            )
        ');
        $pdo->exec("INSERT INTO tmpTableName (userId,status) VALUES ('foo', 0)");
        $pdo->exec("INSERT INTO tmpTableName (userId,status) VALUES ('bar', 0)");
    }

    imprime

    client version: mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
    server version: 5.5.25a
    before:
    foo, 0
    bar, 0
    after:
    foo, 1
    bar, 0

    en mi máquina

    Acabo de darme cuenta de que era un par de citas causando el problema.

    OriginalEl autor VolkerK

  4. 1

    No está llamando a la bindParam método en cualquier lugar, ¿por qué? Justo antes de invocar execute, trate de añadir

    $stmt->bindParam(':userid', $_SESSION['userid'], PDO::PARAM_INT);
    $stmt->bindParam(':status', $status, PDO::PARAM_STR);

    Y, a continuación, simplemente llame a $stmt->execute(); ver cómo funciona para usted. También a su vez, los mensajes de error de hasta el total, y después de crear instancias de su instancia de PDO, agregar este $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); para asegurar que los errores siempre se produce.

    los documentos son cosas útiles

    Pasar una matriz a ejecutar es igualmente válido, no utilizando bindParam no es intrínsecamente malo. El bindParam enfoque está bien, pero no es la causa raíz del problema en este caso.
    Lo sé, pero cuando se encuentra con dificultades, mi primera reacción es ir a tomar el más seguro, es cierto que: en el caso de php a menudo contra-intuitivo, la ruta y ver si eso falla, entonces poco a poco introducir el código que causó el problema, como un bono: bindParam permite utilizar el PDO::* constantes de tipo

    OriginalEl autor Elias Van Ootegem

Dejar respuesta

Please enter your comment!
Please enter your name here