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. Para obtener más información, vea la sección Notas.

Valor devuelto

Devuelve un PDOStatement objeto si se ejecuta correctamente. Si se produce un error, devuelve un PDOException objeto o false en función del valor de PDO::ATTR_ERRMODE.

Comentarios

Los controladores de Microsoft para PHP para SQL Server no evalúan las 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 PDO::CURSOR_SCROLLen , puede usar PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE para establecer el tipo de cursor desplazable, que se describe más adelante en este artículo.

Consulte Tipos de cursor (PDO_SQLSRV controlador) para obtener más información sobre los conjuntos de resultados y los cursores en el PDO_SQLSRV controlador.
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. Consulte más adelante en este artículo los valores que puede tomar este atributo.
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 True, especifica la ejecución directa de consultas. False significa ejecución de instrucciones preparadas. 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 siguiente matriz para PDO::prepare 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 del lado servidor (sin búfer), que permite acceder a las filas en cualquier orden y reflejar los cambios en la base de datos.
PDO::SQLSRV_CURSOR_KEYSET Crea un cursor de conjunto de claves de servidor. Un cursor de conjunto de claves no actualiza el recuento de filas si se elimina una fila de la tabla (se devuelve una fila eliminada sin valores).
PDO::SQLSRV_CURSOR_STATIC Crea un cursor estático del lado servidor, que permite acceder a las filas en cualquier orden, pero no refleja los cambios en la base de datos.

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

Puede cerrar un PDOStatement objeto llamando a unset:

unset($stmt);

Ejemplo de solo avance

En este ejemplo se muestra cómo usar PDO::prepare con marcadores de parámetro y un cursor de solo 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 del lado 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

Los dos fragmentos de código siguientes muestran cómo usar PDO::prepare con datos destinados a columnas / char varchar. Dado que la codificación predeterminada para 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 PDO_SQLSRV controlador reemplaza internamente todos los marcadores de posición por los parámetros enlazados por 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 mediante su característica de consulta parametrizada para los parámetros de enlace. 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 Transact-SQL. Además, SQL Server tiene un límite de enlace de 2100 parámetros.

Nota:

Con emular 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 contienen 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 PDO_SQLSRV controlador 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(). De lo contrario, el controlador usa la codificación especificada en PDO::__construct() o PDO::setAttribute().

Además, a partir de la versión 5.8.0, al usar PDO::p repare con establecido en PDO::ATTR_EMULATE_PREPARES true, el usuario puede usar los tipos de cadena extendidos introducidos en PHP 7.2 para asegurarse de que se usa el N prefijo. Los fragmentos de código siguientes 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.

Usar 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]);

Uso de la constante PDO PDO::P ARAM_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::P ARAM_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, algunas limitaciones resultan cuando la característica de consulta con parámetros no está en uso.

  • No funciona para los parámetros enlazados 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 enlazados 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 argumento para un parámetro de salida, no se produce ninguna excepción porque el controlador no puede detectar el parámetro de salida. Sin embargo, la variable que proporciona el usuario para el parámetro de salida permanece sin cambios.
  • Los marcadores de posición duplicados para un parámetro codificado binario no funcionan.