In MySQL we used the mysqli_stmt_bind_param to bind parameters.
What should I use to bind parameters in sqlsrv?
$sql = "SELECT * FROM dbo.[user] WHERE username = ? and password = ?";
$stmt = sqlsrv_prepare($conn, $sql, $params);
if($stmt === false){
die( print_r( sqlsrv_errors(), true));
}
How can I bind this parameters? This is a php file and I need to bind them without pdo.
You don't explicitly bind the parameters by using another function, you do it when preparing the statement.
See the example from the manual.
$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));
}
}
Related
Im studying this PHP script on how to prepare for multiple execution of a UPDATE statement. The script below shows update for 1 column using prepared statement.
Example from PHP manual https://www.php.net/manual/en/function.sqlsrv-prepare.php
<?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));
}
}
?>
What if I have multiple column to update, how do I create an array to bound multiple variables to a prepared statement in foreach?
New update SQL statement with 3 columns.
$sql = "UPDATE Table_1
SET OrderQty = ?,
SET ProductName = ?,
SET ProductPRice = ?
WHERE SalesOrderID = ?";
You may try to build the array with the actual parameters values differently. And fix the syntax of the UPDATE statement:
<?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 = ?, ProductName = ?, ProductPrice = ?
WHERE SalesOrderID = ?
";
// Initialize parameters and prepare the statement.
// Variables $qty and $id are bound to the statement, $stmt.
$qty = 0; $name = ""; $price = 0.00; $id = 0;
$stmt = sqlsrv_prepare($conn, $sql, array(&$qty, &$name, &$price, &$id));
if ($stmt === false) {
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(
array("qty" => 10, "name" => "Product1", "price" => 10.01, "id" => 1),
array("qty" => 20, "name" => "Product2", "price" => 10.02, "id" => 2),
array("qty" => 30, "name" => "Product3", "price" => 10.03, "id" => 3)
);
// Execute the statement for each order.
foreach ($orders as $order) {
// Because $id and $qty are bound to $stmt1, their updated
// values are used with each execution of the statement.
$qty = $order["qty"];
$name = $order["name"];
$price = $order["price"];
$id = $order["id"];
if (sqlsrv_execute($stmt) === false) {
die( print_r( sqlsrv_errors(), true));
}
}
// End
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
I want to update a table where column user_id has values, stored in an array, but I get this error:
Array ( [0] => Array ( [0] => 42S22 [SQLSTATE] => 42S22 [1] => 207
[code] => 207 [2] => [Microsoft][ODBC Driver 17 for SQL Server][SQL
Server]Invalid column name 'Array'. [message] => [Microsoft][ODBC
Driver 17 for SQL Server][SQL Server]Invalid column name 'Array'. ) )
This is my code:
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE
ano=".$ano." and
mes=".$mes." and
dia".$dia."='T' and
comida_habitual ='T'
";
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
array_push($usuarios_comida_habitual,$row['usuario_id']);
}
// Una vez que tenemos los usuarios Que han fichado para ese dia hacemos un Update
$sql_update = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO IN (".$usuarios_comida_habitual.") AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$stmt2 = sqlsrv_query( $conn2, $sql_update);
if( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
}
else
{
echo 'eureka';
}
Is it possible that the way the array was passed is wrong? Or is it possible to put the condition that I want to implement what userid should be in that array?
I found this
array_walk($usuarios_comida_habitual , 'intval');
$ids = implode(',', $usuarios_comida_habitual);
i Do this before generating $sql_update
Consider a single SQL query without any loop since IN supports subqueries. And since connections run across different servers, consider OPENROWSET for ad hoc queries. Adjust ODBC connection string parameters and [database].[schema] identifiers accordingly. (Note: default schema is dbo).
$sql = "UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE VLD_PRESENCIA_CODUSUARIO
IN (SELECT sub.usuario_id
FROM OPENROWSET('SQLNCLI',
'DRIVER={SQL Server};SERVER=ServerName;UID=userID;PWD=password',
'SELECT * FROM [database].[schema].control_asistencias') sub
WHERE sub.ano = ?
AND sub.mes = ?
AND sub.dia".$dia." = 'T'
AND sub.comida_habitual = 'T')
AND VLD_PRESENCIA_COMIDA_HABITUAL = 'T'";
$prms = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $prms);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}
Although using an array for the IN clause has already a similar answer, you may try to use the sqlsrv_prepare()\sqlsrv_execute() combination to prepare a statement and execute it multiple times. But in both cases you need to consider the following:
Always try to use parameters in your statements to prevent possible SQL injection issues.
When the column name is used dynamically (possible wrong design), check the genarated name using sys.columns system catalog view to prevent possible SQL injection issues.
Note, the reason for your error is the fact, that you are trying to build an SQL statement concatenating a string literal and a PHP array.
The following example, based on your code and using parameterized queries, is a possible solution to your problem:
<?php
// SELECT statement
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE ano = ? AND mes = ? AND dia".$dia." = 'T' AND comida_habitual = 'T'
";
$params = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$usuarios_comida_habitual[] = $row['usuario_id'];
}
// Multiple UPDATE statements
$sql = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO = ? AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$usuario = 0;
$params2 = array(&$usuario);
$stmt2 = sqlsrv_prepare($conn2, $sql, $params2);
if ( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
}
foreach ($usuarios_comida_habitual as $usuario) {
if (sqlsrv_execute($stmt2) === false ) {
die( print_r( sqlsrv_errors(), true) );
} else {
echo 'eureka';
}
}
?>
If you want to execute a single UPDATE statement, the following approach is an option, but again with parameterized statement:
<?php
// SELECT statement
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE ano = ? AND mes = ? AND dia".$dia." = 'T' AND comida_habitual = 'T'
";
$params = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$usuarios_comida_habitual[] = $row['usuario_id'];
}
// Single UPDATE statement
$usuarios_placeholders = substr(str_repeat(',?', count($usuarios_comida_habitual)), 1);
$sql = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO IN (".$usuarios_placeholders.") AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$stmt2 = sqlsrv_query($conn2, $sql, $usuarios_comida_habitual);
if ( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
} else {
echo 'eureka';
}
?>
I am trying to execute a sql server stored procedure from php. Stored procedure returns a output value. I want that value in php to display in webpage.
Everything works fine except the output value returns 0 in php.. but the row is getting inserted perfectly. the output value shows as 0. annoyed where I have made the mistake. Below is my php code
require('db.php');
$billno = "REF0001";
$retsno = 0.0;
$sp_name = "{call testinsert( ?, ? )}";
$params = array(
array($billno, SQLSRV_PARAM_IN),
array($retsno, SQLSRV_PARAM_OUT)
);
/* Execute the query. */
$stmt3 = sqlsrv_query( $conn, $sp_name, $params);
if( $stmt3 === false )
{
echo "Error in executing statement 3.\n";
die( print_r( sqlsrv_errors(), true));
}
echo "Inserted Retuern Sno for ".$billno." is ". $retsno. ".";
and my stored procedure is
create procedure testinsert(#bill_no VARCHAR(20),#RetSno INT OUTPUT)
as
begin
insert into testable values(#bill_no,GETDATE())
set #RetSno = ##IDENTITY
return
end
Maybe you missed scrollable. https://msdn.microsoft.com/en-us/library/hh487160(v=sql.105).aspx
$stmt3 = sqlsrv_query( $conn, $sp_name, $params, array( "Scrollable" => 'static'));
Before you use your echo, add the following line to read the next line:
sqlsrv_fetch($stmt3);
Then you can select the first field of the response, which should be your parameter, with sqlsrv_get_field():
$id = sqlsrv_get_field(0);
I had the same case, and solved it using:
sqlsrv_next_result($stmt);
at the end of the instruction. Here I put part of my code in case it helps you.
$totalPaginas = 0;
$result = array();
$query = "EXEC DBO.SPS_EJECUTAR_CONSULTA #ReporteID = ?, #FilasPorPagina = ?, #NroPagina = ?, #TotalPaginas = ?";
$params = array(
array(&$reporteid, SQLSRV_PARAM_IN),
array(&$filasPorPagina, SQLSRV_PARAM_IN),
array(&$nroPagina, SQLSRV_PARAM_IN),
array(&$totalPaginas, SQLSRV_PARAM_OUT)
);
$stmt = sqlsrv_prepare($this->db, $query, $params);
if( !$stmt ) {
// show errors
}
$result = sqlsrv_execute($stmt);
if( !$result ) {
// show errors
}
$data = array();
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$data[] = $row;
}
sqlsrv_next_result($stmt);
var_dum($data);
echo('Total Paginas: '.$totalPaginas);
Officially tells you how to do it here:
https://learn.microsoft.com/en-us/sql/connect/php/how-to-retrieve-input-and-output-parameters-using-the-sqlsrv-driver
I am working on a php code where I insert into two tables and want to grab the id from the first table I inserted into, right now I am getting this error: Call to undefined function sqlsrv_field(). I am trying to grab the routine_id from the table routines.
Code:
date_default_timezone_set('Europe/Oslo');
$date = strftime ('%Y-%m-%d');
$time = strftime('%H:%M:%S');
$value = $_GET['Temp'];
$conn = sqlsrv_connect('BILAL' , $conn_array);
$sql = "Insert into routines (date, time, value, emp_id) values ('$date', '$time', '$value', (SELECT id FROM emps WHERE user_name='Arduino'))";
if ( sqlsrv_begin_transaction( $conn ) === false ) {
die( print_r( sqlsrv_errors(), true ));
}
$query = sqlsrv_query( $conn, $sql);
if( $query === false ) {
die( print_r( sqlsrv_errors(), true));
}
sqlsrv_next_result($query);
sqlsrv_fetch($query);
$id = sqlsrv_field($query,0);
$sql2 = "Insert into measure_routines (routine_id, measure_id, pool_id) values ('$id', (Select id from measurements where title='A_Auto_Temperatur'), 1 )";
$stmt = sqlsrv_query( $conn, $sql2);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}
There is no function called sqlsrv_field(). Instead, use sqlsrv_get_field():
...
sqlsrv_next_result($query);
bool fetchStatus = sqlsrv_fetch($query);
if(fetchStatus === false) {
die( print_r( sqlsrv_errors(), true));
}
if(fetchStatus === null) {
// Some work when there are no results in the result set
} else {
$id = sqlsrv_get_field($query, 0);
}
...
This should solve your problem basically. However your code is vulnerable to SQL injection. Instead of giving values directly into the sql query, consider using prepared statements.
There are many articles about that, here is one I found in quick search:
What's the Right Way to Prevent SQL Injection in PHP Scripts?
Try this:
function lastId($queryID) {
sqlsrv_next_result($queryID);
sqlsrv_fetch($queryID);
return sqlsrv_get_field($queryID, 0);
}
$lastInsertedId = lastId($stmt);
I'm having a really annoying problem with a simple query.
So:
INSERT INTO [SapuV2].[dbo].[ALERGIA] ([DESCRIPCION]) OUTPUT INSERTED.PK_ALERGIA VALUES ('test')
PK_ALERGIA is a primary identity key, and i need the new id created.
PHP code:
$sql = "INSERT INTO ALERGIA (DESCRIPCION) OUTPUT INSERTED.PK_ALERGIA VALUES(?)";
$id = 0;
$params = array(
array(&$nombre, SQLSRV_PARAM_IN),
array(&$id, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT)
);
$stmt = sqlsrv_prepare($this->Conn, $sql, $params);
if( sqlsrv_execute($stmt) === false){
die( print_r( sqlsrv_errors(), true) );
}else{
var_dump($id);
}
I'm able to save records on my BD, but $id is always 0 ...
Thanks ;)
Please try this:
INSERT INTO ALERGIA (DESCRIPCION)select #var=scope_identity()
I finally did it, but i'm not proud ...
Using same SQL Query, but change the sqlsrv_execute to a sqlsrv_fetch_array
$sql = "INSERT INTO ALERGIA ([DESCRIPCION]) OUTPUT INSERTED.PK_ALERGIA VALUES (?)";
$params = array(
array(&$nombre, SQLSRV_PARAM_IN)
);
$rows = sqlsrv_query($this->Conn, $sql, $params);
if($rows === false){
die(var_dump(sqlsrv_errors()));
}else{
while($row = sqlsrv_fetch_array($rows, SQLSRV_FETCH_ASSOC)){
var_dump($row);
}
}