2024 年 PHP 大会日本站

sqlsrv_prepare

(无版本信息可用,可能仅在 Git 中)

sqlsrv_prepare准备执行查询

描述

sqlsrv_prepare(
    资源 $conn,
    字符串 $sql,
    数组 $params = ?,
    数组 $options = ?
): 混合

准备执行查询。此函数非常适合准备将使用不同的参数值多次执行的查询。

参数

conn

sqlsrv_connect() 返回的连接资源。

sql

定义要准备和执行的查询的字符串。

params

在执行参数化查询时指定参数信息的数组。数组元素可以是以下任何一种:

  • 字面值
  • PHP 变量
  • 具有以下结构的数组:array($value [, $direction [, $phpType [, $sqlType]]])
下表描述了上述数组结构中的元素

数组结构
元素 描述
$value 字面值、PHP 变量或 PHP 按引用变量。
$direction (可选) 用于指示参数方向的以下 SQLSRV 常量之一:SQLSRV_PARAM_IN、SQLSRV_PARAM_OUT、SQLSRV_PARAM_INOUT。默认值为 SQLSRV_PARAM_IN。
$phpType (可选) 一个 SQLSRV_PHPTYPE_* 常量,指定返回值的 PHP 数据类型。
$sqlType (可选) 一个 SQLSRV_SQLTYPE_* 常量,指定输入值的 SQL Server 数据类型。
options

指定查询属性选项的数组。支持的键在下表中描述

查询选项
描述
QueryTimeout 一个正整数。 设置查询超时时间(秒)。默认情况下,驱动程序将无限期等待结果。
SendStreamParamsAtExec truefalse(默认为 true 配置驱动程序在执行时发送所有流数据 (true),或者分块发送流数据 (false)。默认值为 true。有关更多信息,请参阅 sqlsrv_send_stream_data()
Scrollable SQLSRV_CURSOR_FORWARD、SQLSRV_CURSOR_STATIC、SQLSRV_CURSOR_DYNAMIC 或 SQLSRV_CURSOR_KEYSET 请参阅 Microsoft SQLSRV 文档中的 » 指定游标类型和选择行

返回值

成功时返回语句资源,如果发生错误则返回 false

范例

示例 #1 sqlsrv_prepare() 示例

此示例演示如何使用 sqlsrv_prepare() 准备语句,并使用 sqlsrv_execute() 多次重新执行它(使用不同的参数值)。

<?php
$serverName
= "serverName\sqlexpress";
$connectionInfo = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if(
$conn === false) {
die(
print_r( sqlsrv_errors(), true));
}

$sql = "UPDATE Table_1
SET OrderQty = ?
WHERE SalesOrderID = ?"
;

// 初始化参数并准备语句。
// 变量 $qty 和 $id 绑定到语句 $stmt。
$qty = 0; $id = 0;
$stmt = sqlsrv_prepare( $conn, $sql, array( &$qty, &$id));
if( !
$stmt ) {
die(
print_r( sqlsrv_errors(), true));
}

// 设置 SalesOrderDetailID 和 OrderQty 信息。
// 此数组以键值对的形式将订单 ID 映射到订单数量。
$orders = array( 1=>10, 2=>20, 3=>30);

// 为每个订单执行语句。
foreach( $orders as $id => $qty) {
// 因为 $id 和 $qty 绑定到 $stmt1,所以它们的更新值将
// 用于语句的每次执行。
if( sqlsrv_execute( $stmt ) === false ) {
die(
print_r( sqlsrv_errors(), true));
}
}
?>

注释

当您准备使用变量作为参数的语句时,变量将绑定到该语句。这意味着,如果您更新变量的值,则下次执行语句时,它将使用更新的参数值运行。对于计划只执行一次的语句,请使用 sqlsrv_query()

参见

添加注释

用户贡献的注释 2 条注释

4
tuxedobob
9 年前
在使用 sqlsrv_prepare 将变量绑定到语句后,请小心处理您的变量。

考虑以下情况

<?php
$dude
= '';
$time = new DateTime();
$sql = "INSERT INTO my_table (person, timein) VALUES (?, ?)";
$stmt = sqlsrv_prepare($conn, $sql, array(&$dude, &$time));

...
// 之后很多行

foreach ($times as &$time) {
// 执行一些操作
}

// 更后面...
$time = $times['start'];
if(
sqlsrv_execute( $stmt ) === false ) {
die(
print_r( sqlsrv_errors(), true));
}
?>

我做了类似的事情。我在开始时准备了一个语句,在中间再次使用了该变量,然后在运行查询之前设置了我想要的值。

问题是,我将变量用作迭代器而不是简单的标量。这导致 PHP 使用内存中的不同位置,而它之前绑定的位置无效。因此,SQL 只插入了默认日期/时间。

更糟糕的是,因为 SQL 只插入了默认值,所以它没有抛出任何错误,在尝试调试它时,我做了类似这样的事情

<?php
var_dump
($time);
sqlsrv_execute($stmt);
$q = "SELECT * FROM my_table WHERE id=@@IDENTITY";
$r = sqlsrv_query($conn, $q);
$row = sqlsrv_fetch_array($r); $id = $row[0];
var_dump($row['time']);
?>

看起来你正在向 SQL 发送正确的数据,却看到它吐出完全不同的东西,这绝对令人抓狂。

因此,如果 SQL 似乎使用预处理语句插入垃圾数据,请确保您没有在任何其他地方使用这些变量。
-2
matt at bigbadweb dot co dot uk
10年前
如何正式指定参数并获取输出的示例。
<?php

// 设置连接
$serverName = "serverName\sqlexpress";
$connectionInfo = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if(
$conn === false) {
die(
print_r( sqlsrv_errors(), true));
}

// 指定参数 - 必须是可以通过引用传递的变量!
$myparams['Item_ID'] = intval(-2);
$myparams['Item_Name'] = "Foo";

// 设置 proc 参数数组 - 确保通过引用传递参数
$procedure_params = array(
array(&
$myparams['Item_ID'], SQLSRV_PARAM_OUT),
array(&
$myparams['Item_Name'], SQLSRV_PARAM_OUT)
);

// 执行过程,{call stp_Create_Item (@Item_ID = ?, @Item_Name = ?)} 在我的实验中似乎会失败并出现各种错误
$sql = "EXEC stp_Create_Item @Item_ID = ?, @Item_Name = ?";

$stmt = sqlsrv_prepare($conn, $sql, $procedure_params);

if( !
$stmt ) {
die(
print_r( sqlsrv_errors(), true));
}

if(
sqlsrv_execute($stmt)){
while(
$res = sqlsrv_next_result($stmt)){
// 确保所有结果集都被遍历,因为输出参数可能直到发生这种情况才会设置
}
// 输出参数现在已设置,
print_r($params);
print_r($myparams);
}else{
die(
print_r( sqlsrv_errors(), true));
}
?>
To Top