PHP Conference Japan 2024

sqlsrv_execute

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

sqlsrv_execute执行使用 sqlsrv_prepare() 预准备的语句

描述

sqlsrv_execute(资源 $stmt): 布尔值

执行使用 sqlsrv_prepare() 预准备的语句。此函数非常适合使用不同的参数值多次执行预准备语句。

参数

stmt

sqlsrv_prepare() 返回的语句资源。

返回值

成功时返回 true,失败时返回 false

示例

示例 #1 sqlsrv_execute() 示例

此示例演示如何使用 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()

参见

添加注释

用户贡献的注释 3 条注释

tuxedobob
8 年前
如果您习惯使用 sqlsrv_query,您可能习惯了以下流程

<?php
$query
= "SELECT * FROM mytable WHERE id=?";
$result = sqlsrv_query($conn, $query, array($myID));
$row = sqlsrv_fetch_array($result);
?>

鉴于此,您可能认为以下方法有效

<?php
$myID
= 0;
$query = "SELECT * FROM mytable WHERE id=?";
$stmt = sqlsrv_prepare($conn, $query, array(&$myID));
$result = sqlsrv_execute($stmt);
$row = sqlsrv_fetch_array($result);
?>

事实并非如此。原因是 sqlsrv_execute,如上所述,在成功或失败时分别返回 true 或 false。包含结果的变量实际上是 $stmt。将最后一行更改为

<?php
$row
= sqlsrv_fetch_array($stmt);
?>

它就可以按预期工作了。
vavra at 602 dot cz
6 年前
注意!
如果 sql 包含 INSERT、UPDATE 或 DELETE 语句,则必须使用受影响的行数。sqlsrv_query 返回一个 sql 游标,如果结果不是 false,则必须读取该游标以完成事务。这对于 sqlsrv_execute 也同样有效。在这种情况下,也必须使用预准备语句句柄 $smt 读取游标。

另一种解决方案是在 sqlsrv 语句以及所有调用的过程、函数和触发器的顶部放置 SET NOCOUNT ON。

我们实际上已经观察到,包含 500 个插入的 sql 语句,如果没有返回 false,则只插入了 368 个。通过添加 SET NOCOUNT ON 或读取游标的所有行,所有行都已插入。

参见结果处理 (ODBC):https://docs.microsoft.com/en-us/sql/relational-databases/native-client-odbc-results/processing-results-odbc 每个 INSERT、UPDATE 和 DELETE 语句都返回一个结果集,其中只包含受修改影响的行数。当应用程序调用 SQLRowCount 时,此计数将可用。ODBC 3.x 应用程序必须调用 SQLRowCount 来检索结果集,或者调用 SQLMoreResults 来取消它。当应用程序执行包含多个 INSERT、UPDATE 或 DELETE 语句的批处理或存储过程时,必须使用 SQLRowCount 处理每个修改语句的结果集,或者使用 SQLMoreResults 取消它。这些计数可以通过在批处理或存储过程中包含 SET NOCOUNT ON 语句来取消。
esundberg at nitelusa dot com
4 年前
PDO 预处理和执行示例

代码
----------------------------------------
print "<h1>PDO 示例</h1>";

print "<h2>PDO 连接</h2>";
try {
$pdo = new PDO("sqlsrv:server=$sql_server;Database=$sql_database",$sql_username,$sql_password,['ReturnDatesAsStrings'=>true]);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "连接失败: " . $e->getMessage();
die("数据库连接错误");

}

print "<h2>检查 PDO 连接</h2>";
if($pdo === false) {
print "无数据库连接<br>";
} else {
print "数据库连接成功<br>";
}

print "<h2>PDO 查询示例 1,包含 SQL 注入风险</h2>";
print "我个人更喜欢 PDO,因为它支持按名称绑定参数。<br>";
$sql = "SELECT username, active FROM users WHERE username = :username";
print "SQL: $sql\n";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':username', $username);
$stmt->execute();
while($r = $stmt->fetch(PDO::FETCH_OBJ)) {
print_r($r);
}

------------------------------------------------------
PDO 示例
PDO 连接
检查 PDO 连接
数据库连接成功
PDO 查询示例 1,包含 SQL 注入风险
我个人更喜欢 PDO,因为它支持按名称绑定参数。
SQL: SELECT username, active FROM users WHERE username = :username
stdClass 对象
(
[username] => admin
[active] => 1
)
To Top