PDO::prepare

Descargar controlador PHP

Prepara una instrucción para su ejecución.

Sintaxis

PDOStatement PDO::prepare ( $statement [, array(key_pair)] )

Parámetros

$instrucción: una cadena que contiene la instrucción SQL.

key_pair: una matriz que contiene un valor y un nombre de atributo. Vea la sección Comentarios para obtener más información.

Valor devuelto

Devuelve un objeto PDOStatement si se ejecuta correctamente. En caso de error, devuelve un objeto PDOException o false, según el valor de PDO::ATTR_ERRMODE.

Observaciones

Los Controladores de Microsoft para PHP para SQL Server no evalúan instrucciones preparadas hasta la ejecución.

En la siguiente tabla se incluyen los posibles valores key_pair.

Clave Descripción
PDO::ATTR_CURSOR Especifica el comportamiento del cursor. El valor predeterminado es PDO::CURSOR_FWDONLY, un cursor de avance que no es desplazable. PDO::CURSOR_SCROLL es un cursor desplazable.

Por ejemplo, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ).

Cuando se establece en PDO::CURSOR_SCROLL, puede usar PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE para establecer el tipo de cursor desplazable, que se describe a continuación.

Vea Tipos de cursor (controlador PDO_SQLSRV) para obtener más información sobre los conjuntos de resultados y los cursores del controlador PDO_SQLSRV.
PDO::ATTR_EMULATE_PREPARES De forma predeterminada, este atributo es false, que se puede cambiar por PDO::ATTR_EMULATE_PREPARES => true. Vea Emulate Prepare para consultar detalles y ejemplos.
PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE Especifica el tipo de cursor desplazable. Es válido solo cuando PDO::ATTR_CURSOR está establecido en PDO::CURSOR_SCROLL. Vea a continuación los valores que este atributo puede adoptar.
PDO::SQLSRV_ATTR_DECIMAL_PLACES Especifica el número de lugares decimales al dar formato a los valores de moneda obtenidos. Esta opción solo funciona cuando PDO::SQLSRV_ATTR_FORMAT_DECIMALS es true. Para más información, vea Aplicación de formato a cadenas decimales y valores de moneda (controlador PDO_SQLSRV).
PDO::SQLSRV_ATTR_DIRECT_QUERY Cuando es True, especifica la ejecución de una consulta directa. False implica la ejecución de una instrucción preparada. Para más información sobre PDO::SQLSRV_ATTR_DIRECT_QUERY, vea Ejecución de la instrucción preparada o directa en el controlador PDO_SQLSRV.
PDO::SQLSRV_ATTR_ENCODING PDO::SQLSRV_ENCODING_UTF8 (valor predeterminado)

PDO::SQLSRV_ENCODING_SYSTEM

PDO::SQLSRV_ENCODING_BINARY
PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE Especifica si debe recuperar tipos de fecha y hora como objetos PHP DateTime. Para más información, vea: Cómo: Recuperación de los tipos de fecha y hora como objetos de fecha y hora PHP mediante el controlador PDO_SQLSRV.
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE Controla los resultados numéricos de las columnas en relación con los tipos SQL numéricos. Para obtener más información, consulte PDO::setAttribute.
PDO::SQLSRV_ATTR_FORMAT_DECIMALS Especifica si se agregan ceros iniciales a las cadenas decimales cuando proceda. Si se establece, esta opción habilita la opción PDO::SQLSRV_ATTR_DECIMAL_PLACES para aplicar formato a los tipos de divisa. Para más información, vea Aplicación de formato a cadenas decimales y valores de moneda (controlador PDO_SQLSRV).
PDO::SQLSRV_ATTR_QUERY_TIMEOUT Para obtener más información, consulte PDO::setAttribute.

Cuando se usa PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, puede usar PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE para especificar el tipo de cursor. Por ejemplo, pase la matriz siguiente a PDO::prepare para establecer un cursor dinámico:

array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_DYNAMIC));

En la tabla siguiente se muestran los valores posibles para PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE. Para más información sobre los cursores desplazables, vea Tipos de cursor (controlador PDO_SQLSRV).

Valor Descripción
PDO::SQLSRV_CURSOR_BUFFERED Crea un cursor estático del lado cliente (en búfer), que almacena en búfer el conjunto de resultados en memoria en el equipo cliente.
PDO::SQLSRV_CURSOR_DYNAMIC Crea un cursor dinámico de servidor (no almacenado en búfer), que le permite acceder a las filas en cualquier orden y reflejará los cambios de la base de datos.
PDO::SQLSRV_CURSOR_KEYSET Crea un cursor de conjunto de claves de servidor. Los cursores de conjunto de claves no actualizan el recuento de filas si se elimina una fila de la tabla (las filas eliminadas se devuelven sin valores).
PDO::SQLSRV_CURSOR_STATIC Crea un cursor estático de servidor, que le permite acceder a las filas en cualquier orden, pero no reflejará los cambios de la base de datos.

PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL implica PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_STATIC.

Puede cerrar un objeto PDOStatement mediante una llamada a unset:

unset($stmt);

Ejemplo de solo avance

En este ejemplo se muestra cómo usar PDO::prepare con marcadores de parámetros y un cursor de sólo avance.

<?php
$database = "Test";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");

$col1 = 'a';
$col2 = 'b';

$query = "insert into Table1(col1, col2) values(?, ?)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1  ) );
$stmt->execute( array( $col1, $col2 ) );
print $stmt->rowCount();
echo "\n";

$query = "insert into Table1(col1, col2) values(:col1, :col2)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1  ) );
$stmt->execute( array( ':col1' => $col1, ':col2' => $col2 ) );
print $stmt->rowCount();

unset($stmt);
?>

Ejemplo de cursor estático

En este ejemplo se muestra cómo usar PDO::prepare con un cursor estático de servidor. Para ver un ejemplo en el que se muestre un cursor del lado cliente, vea Tipos de cursor (controlador PDO_SQLSRV).

<?php
$database = "AdventureWorks";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");

$query = "select * from Person.ContactType";
$stmt = $conn->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();

echo "\n";

while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ){
   print "$row[Name]\n";
}
echo "\n..\n";

$row = $stmt->fetch( PDO::FETCH_BOTH, PDO::FETCH_ORI_FIRST );
print_r($row);

$row = $stmt->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, 1 );
print "$row[Name]\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT );
print "$row[1]\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_PRIOR );
print "$row[1]..\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_ABS, 0 );
print_r($row);

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_LAST );
print_r($row);
?>

Ejemplo de destino

En los dos fragmentos de código siguientes se muestra cómo usar PDO::prepare con los datos destinados a las columnas CHAR/VARCHAR. Dado que la codificación predeterminada de PDO::prepare es UTF-8, el usuario puede usar la opción PDO::SQLSRV_ENCODING_SYSTEM para evitar conversiones implícitas.

Opción 1

$options = array(PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_SYSTEM);
$statement = $pdo->prepare(
  'SELECT *
   FROM myTable
   WHERE myVarcharColumn = :myVarcharValue',
  $options
);

$statement->bindValue(':myVarcharValue', 'my data', PDO::PARAM_STR);

Opción 2

$statement = $pdo->prepare(
  'SELECT *
   FROM myTable
   WHERE myVarcharColumn = :myVarcharValue'
);
$p = 'my data';
$statement->bindParam(':myVarcharValue', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_SYSTEM);

Ejemplo de preparación

En este ejemplo se muestra cómo usar PDO::prepare con PDO::ATTR_EMULATE_PREPARES establecido en true.

<?php
$serverName = "yourservername";
$username = "yourusername";
$password = "yourpassword";
$database = "tempdb";
$conn = new PDO("sqlsrv:server = $serverName; Database = $database", $username, $password);

$pdo_options = array();
$pdo_options[PDO::ATTR_EMULATE_PREPARES] = true;
$pdo_options[PDO::SQLSRV_ATTR_ENCODING] = PDO::SQLSRV_ENCODING_UTF8;

$stmt = $conn->prepare("CREATE TABLE TEST([id] [int] IDENTITY(1,1) NOT NULL,
                                          [name] nvarchar(max))",
                                          $pdo_options);
$stmt->execute();

$prefix = '가각';
$name = '가각ácasa';
$name2 = '가각sample2';

$stmt = $conn->prepare("INSERT INTO TEST(name) VALUES(:p0)", $pdo_options);
$stmt->execute(['p0' => $name]);
unset($stmt);

$stmt = $conn->prepare("SELECT * FROM TEST WHERE NAME LIKE :p0", $pdo_options);
$stmt->execute(['p0' => "$prefix%"]);
foreach ($stmt as $row) {
    echo "\n" . 'FOUND: ' . $row['name'];
}

unset($stmt);
unset($conn);
?>

El controlador PDO_SQLSRV reemplaza internamente todos los marcadores de posición con los parámetros que están enlazados mediante PDOStatement::bindParam(). Por tanto, se envía al servidor una cadena de consulta SQL sin ningún marcador de posición. Considere este ejemplo:

$statement = $PDO->prepare("INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)");
$statement->bindParam(:cus_name, "Cardinal");
$statement->bindParam(:con_name, "Tom B. Erichsen");
$statement->execute();

Con PDO::ATTR_EMULATE_PREPARES establecido en false (el caso predeterminado), los datos enviados a la base de datos son:

"INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)"
Information on :cus_name parameter
Information on :con_name parameter

El servidor ejecuta la consulta con su característica de consulta con parámetros para enlazar parámetros. Por otro lado, con PDO::ATTR_EMULATE_PREPARES establecido en true, la consulta enviada al servidor es básicamente:

"INSERT into Customers (CustomerName, ContactName) VALUES ('Cardinal', 'Tom B. Erichsen')"

Establecer PDO::ATTR_EMULATE_PREPARES en true puede omitir algunas restricciones en SQL Server. Por ejemplo, SQL Server no admite parámetros con nombre o posicionales en algunas cláusulas de Transact-SQL. Además, SQL Server tiene un límite de 2100 parámetros de enlace.

Nota

Con emulate prepares establecido en true, la seguridad de las consultas con parámetros no está en vigor. Por lo tanto, la aplicación debe asegurarse de que los datos enlazados a los parámetros no contengan código Transact-SQL malintencionado.

Encoding

Si el usuario desea enlazar parámetros con distintas codificaciones (por ejemplo, UTF-8 o binario), el usuario debe especificar claramente la codificación en el script PHP.

El controlador PDO_SQLSRV comprueba primero la codificación especificada en PDO::bindParam() (por ejemplo, $statement->bindParam(:cus_name, "Cardinal", PDO::PARAM_STR, 10, PDO::SQLSRV_ENCODING_UTF8)).

Si no se encuentra, el controlador comprueba si cualquier codificación está establecida en PDO::prepare() o PDOStatement::setAttribute(). En caso contrario, el controlador utilizará la codificación especificada en PDO::__construct() o PDO::setAttribute().

Además, a partir de la versión 5.8.0, cuando se usa PDO::prepare con PDO::ATTR_EMULATE_PREPARES establecido en true, el usuario puede usar los tipos de cadenas extendidas introducidos en PHP 7.2 para asegurarse de que se usa el prefijo de N. En los fragmentos de código siguientes se muestran varias alternativas.

Nota

De forma predeterminada, emulate prepares está establecido en false, en cuyo caso se omitirán las constantes de cadena PDO extendidas.

Uso de la opción de controlador PDO::SQLSRV_ENCODING_UTF8 al enlazar

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8);
$stmt->execute();

Uso del atributo PDO::SQLSRV_ATTR_ENCODING

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true, PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);

Usar la constante PDO PDO::PARAM_STR_NATL

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR | PDO::PARAM_STR_NATL);
$stmt->execute();

Establecer el tipo de parámetro de cadena predeterminado PDO::PARAM_STR_NATL

$conn->setAttribute(PDO::ATTR_DEFAULT_STR_PARAM, PDO::PARAM_STR_NATL);
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);

Limitaciones

Como puede ver, el enlace lo realiza el controlador internamente. Se envía una consulta válida al servidor para su ejecución sin ningún parámetro. En comparación con el caso normal, se producen algunas limitaciones cuando no se usa la característica de consulta con parámetros.

  • No funciona para los parámetros que se enlazan como PDO::PARAM_INPUT_OUTPUT.
    • Cuando el usuario especifica PDO::PARAM_INPUT_OUTPUT en PDO::bindParam(), se produce una excepción de PDO.
  • No funciona para los parámetros que se enlazan como parámetros de salida.
    • Cuando el usuario crea una instrucción preparada con marcadores de posición que están destinados a los parámetros de salida (es decir, con un signo igual inmediatamente después de un marcador de posición, como SELECT ? = COUNT(*) FROM Table1), se produce una excepción PDO.
    • Cuando una instrucción preparada invoca un procedimiento almacenado con un marcador de posición como el argumento para un parámetro de salida, no se lanza ninguna excepción porque el controlador no puede detectar el parámetro de salida. Sin embargo, la variable que el usuario proporciona para el parámetro de salida permanecerá sin cambios.
  • Los marcadores de posición duplicados para un parámetro codificado como binario no funcionarán.

Consulte también

Clase PDO

PDO