Be careful with your variables once you bind them to a statement with sqlsrv_prepare.
Consider the following:
<?php
$dude = '';
$time = new DateTime();
$sql = "INSERT INTO my_table (person, timein) VALUES (?, ?)";
$stmt = sqlsrv_prepare($conn, $sql, array(&$dude, &$time));
...
// many lines later
foreach ($times as &$time) {
//do stuff
}
// later still...
$time = $times['start'];
if( sqlsrv_execute( $stmt ) === false ) {
die( print_r( sqlsrv_errors(), true));
}
?>
I did something like this. I prepared a statement at the start, used the variable again in the middle, and then set the value I wanted before running the query.
Trouble is, I used the variable as an iterator instead of a simple scalar. This caused PHP to use a different location in memory, and the location it was previously bound to was invalid. So SQL simply inserted a default date/time.
Worse, because SQL just inserted a default, it didn't throw any errors, and in trying to debug it, I did something like this:
<?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']);
?>
Having it appear as though you're sending SQL the correct data, and seeing it spitting back something else entirely is absolutely maddening.
So if SQL seems to be inserting garbage with prepared statements, MAKE SURE YOU'RE NOT USING THE VARIABLES ANYWHERE ELSE.sqlsrv_prepare
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
sqlsrv_prepare
Референца за `function.sqlsrv-prepare.php` со подобрена типографија и навигација.
sqlsrv_prepare
(Нема достапни информации за верзијата, можеби е само во Git)
sqlsrv_prepare — Подготвува прашалник за извршување
= NULL
Подготвува прашалник за извршување
Параметри
conn- Подготвува прашалник за извршување. Оваа функција е идеална за подготовка на прашалник што ќе се извршува повеќе пати со различни вредности на параметрите. sqlsrv_connect().
sql- Ресурс за конекција вратен од
params-
Низата што го дефинира прашалникот што треба да се подготви и изврши.
- Низа што специфицира информации за параметрите при извршување на параметарски прашалник. Елементите на низата можат да бидат било што од следново:
- Буквална вредност
- An array with this structure: array($value [, $direction [, $phpType [, $sqlType]]])
Следната табела ги опишува елементите во горната структура на низата: Елемент = NULL $value Структура на низа $direction (optional) Буквална вредност, PHP променлива или PHP променлива по референца. $phpType (optional) Една од следниве SQLSRV константи за означување на насоката на параметарот: SQLSRV_PARAM_IN, SQLSRV_PARAM_OUT, SQLSRV_PARAM_INOUT. Стандардната вредност е SQLSRV_PARAM_IN. $sqlType (optional) SQLSRV_PHPTYPE_* константа што специфицира PHP тип на податоци на вратената вредност. options-
SQLSRV_SQLTYPE_* константа што специфицира SQL Server тип на податоци на влезната вредност.
Низа што специфицира опции за својства на прашалникот. Поддржаните клучеви се опишани во следната табела: Можни индекси на низи за Режими на календар = NULL QueryTimeout Опции за прашалник Позитивен цел број. SendStreamParamsAtExec trueorfalseПоставува временско ограничување на прашалникот во секунди. Стандардно, драјверот ќе чека неодредено време за резултати.true)(стандардно е trueКонфигурира драјверот да испраќа сите податоци од стримот при извршување (false). Стандардно, вредноста е поставена наtrue. За повеќе информации, видете sqlsrv_send_stream_data().Подвижно SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_STATIC, SQLSRV_CURSOR_DYNAMIC, или SQLSRV_CURSOR_KEYSET Константи за известување за грешки Укажува на курсор само напред. За информации за употреба, видете во документацијата на Microsoft SQLSRV.
Вратени вредности
Враќа ресурс за изјава при успех и false аргумент, или
Примери
Пример #1 sqlsrv_prepare() example
Овој пример покажува како да се подготви изјава со 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 = ?";
// Initialize parameters and prepare the statement.
// Variables $qty and $id are bound to the statement, $stmt.
$qty = 0; $id = 0;
$stmt = sqlsrv_prepare( $conn, $sql, array( &$qty, &$id));
if( !$stmt ) {
die( print_r( sqlsrv_errors(), true));
}
// Set up the SalesOrderDetailID and OrderQty information.
// This array maps the order ID to order quantity in key=>value pairs.
$orders = array( 1=>10, 2=>20, 3=>30);
// Execute the statement for each order.
foreach( $orders as $id => $qty) {
// Because $id and $qty are bound to $stmt1, their updated
// values are used with each execution of the statement.
if( sqlsrv_execute( $stmt ) === false ) {
die( print_r( sqlsrv_errors(), true));
}
}
?>Белешки
Кога подготвувате изјава што користи променливи како параметри, променливите се поврзани со изјавата. Ова значи дека ако ги ажурирате вредностите на променливите, следниот пат кога ќе ја извршите изјавата, таа ќе се изврши со ажурирани вредности на параметрите. За изјави што планирате да ги извршите само еднаш, користете sqlsrv_query().
Види Исто така
- sqlsrv_execute() - Извршува изјава подготвена со sqlsrv_prepare
- sqlsrv_query() - Подготвува и извршува прашалник
Белешки од корисници 2 забелешки
Example of how to formally specify the params, AND get output.
<?php
// Setup connection
$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));
}
// specify params - MUST be a variable that can be passed by reference!
$myparams['Item_ID'] = intval(-2);
$myparams['Item_Name'] = "Foo";
// Set up the proc params array - be sure to pass the param by reference
$procedure_params = array(
array(&$myparams['Item_ID'], SQLSRV_PARAM_OUT),
array(&$myparams['Item_Name'], SQLSRV_PARAM_OUT)
);
// EXEC the procedure, {call stp_Create_Item (@Item_ID = ?, @Item_Name = ?)} seems to fail with various errors in my experiments
$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)){
// make sure all result sets are stepped through, since the output params may not be set until this happens
}
// Output params are now set,
print_r($params);
print_r($myparams);
}else{
die( print_r( sqlsrv_errors(), true));
}
?>