PDO::prepare
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_SCROLL en , 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
enPDO::bindParam()
, se produce una excepción de PDO.
- Cuando el usuario especifica
- 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.
- 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
- Los marcadores de posición duplicados para un parámetro codificado binario no funcionan.