query new conexion clase php postgresql pdo

php - new - pdo query



El controlador PHP Postgres PDO no es compatible con la instrucción preparada? (1)

Ver http://www.php.net/manual/en/pdo.prepare.php

Nota:

Las declaraciones preparadas emuladas no se comunican con el servidor de la base de datos, por lo que PDO :: prepare () no verifica la declaración.

(de hecho, las declaraciones realmente preparadas no se envían inmediatamente de todos modos, ver la respuesta a la Q2 a continuación)

De todos modos, puedes emitir:

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);

para obtener sentencias preparadas reales implementadas con el comando SQL PREPARE. Ver http://www.php.net/manual/en/pdo.setattribute.php para más.

En discusiones y pruebas adicionales, surgen dos preguntas:

Q1. ¿Por qué pdo::getAttribute(PDO::ATTR_EMULATE_PREPARES) produce un error?
De hecho, setAttribute no tiene errores, pero getAttribute(PDO::ATTR_EMULATE_PREPARES) dice:

''SQLSTATE [IM001]: el controlador no admite esta función: el controlador no admite ese atributo''

En cuanto a la documentación para pdo :: getAttribute , dice Las constantes que se aplican a las conexiones de la base de datos son las siguientes , y una serie de constantes se siguen de PDO::ATTR_AUTOCOMMIT a PDO::ATTR_TIMEOUT , y es notable que PDO::ATTR_EMULATE_PREPARES no es en ellos Así que estrictamente hablando, no deberíamos esperar que getAttribute(PDO::ATTR_EMULATE_PREPARES) funcione de todos modos.

Ahora, mirando el código fuente para estar seguro, parece que el controlador pdo_pgsql proporciona una función pdo_pgsql_get_attribute que tiene una instrucción switch pdo_pgsql_get_attribute :

  • PDO_ATTR_CLIENT_VERSION
  • PDO_ATTR_SERVER_VERSION
  • PDO_ATTR_CONNECTION_STATUS
  • PDO_ATTR_SERVER_INFO

y eso es. No hay rastro de PDO_ATTR_EMULATE_PREPARES por lo que en última instancia aparece este error.

Por otro lado, la función pdo_pgsql_set_attr tiene una instrucción switch pdo_pgsql_set_attr :

  • PDO_ATTR_EMULATE_PREPARES
  • PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT

que confirma que este atributo se tiene realmente en cuenta cuando se establece. Entonces PDO es simplemente inconsistente con getAttribute que no coincide con setAttribute .

P2: cuando la emulación de preparación es falsa, ¿por qué una afirmación falsa no provoca un error inmediatamente cuando está preparada?

Considere este fragmento de código en pgsql_statement.c :

if (!S->is_prepared) { stmt_retry: /* we deferred the prepare until now, because we didn''t * know anything about the parameter types; now we do */ S->result = PQprepare(H->server, S->stmt_name, S->query, stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0, S->param_types);

Muestra que se usa PQprepare (por lo que es una declaración preparada "real"), pero también que la declaración no se envía inmediatamente al servidor. Es por eso que dbo::prepare("bogus statement") no devolverá falso: en realidad no se envía al servidor por falta de tipos de parámetros.

¿Me estoy volviendo loco o el driver Postgres PDO simplemente no admite declaraciones preparadas, sino que emula el lado del cliente?

El siguiente código devuelve NO ERROR para la llamada a prepare (), aunque debería. En cambio, devuelve el error aplicable cuando se ejecuta execute ().

Editar: Como según Daniel Vérité estoy equivocado, agregué su código sugerido. Aún tengo el error. Mi código ahora se ve como el de abajo, con la línea de Daniel añadida.

<?php $pdo = new PDO("pgsql:host=myhost;dbname=mydatabase"); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // as suggested by Daniel $sth = $pdo->prepare(''COMPLETE GARBAGE''); echo "[prepare] errorInfo = " . print_r($sth->errorInfo(), true); $sth->execute(); echo "[execute] errorInfo = " . print_r($sth->errorInfo(), true);

PHP versión 5.3.15, PHP Postgres cliente versión 9.1.4, servidor de Postgres versión 9.2.1.