No data from Database - php

I wrote an php application which should select data from the database depending on a given date. The date in the Database is stored like 2020-07-03. The code which executes the statement looks like
$from = $_POST['from'];
$to = $_POST['to'];
$sql = "SELECT * FROM Database WHERE Date < $from";
$stmt = sqlsrv_query($conn, $sql);
if($stmt == false){
die( print_r( sqlsrv_errors(), true) );
}
echo $sql;
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC) ) {
echo $row[0].", ".$row[1]."<br />";
}
$from and $to is a range which is given by the user with date-input fields and return the userinput like 2020-07-02. The datatype of the field "Date" is Date. I do not get any error or something similar but it won't execute the while loop and I can't figure out why.

You need to use parameters in your statement. As is mentioned in the documentation, sqlsrv_query() function is well-suited for one-time queries and should be the default choice to execute queries unless special circumstances apply. This function provides a streamlined method to execute a query with a minimum amount of code. The sqlsrv_query function does both statement preparation and statement execution, and can be used to execute parameterized queries.
You need to pass the values of parameters in one of the following ways:
As text using an unambiguous date format (yyyymmdd),
Using extended parameters syntax and the appropriate data type bindings.
Example, based on the code in the question, using text values for dates:
<?php
// Connection
$server = 'server,port';
$database = 'database';
$uid = 'uid';
$pwd = 'pwd';
$cinfo = array(
"ReturnDatesAsStrings" => true,
"Database" => $database,
"UID" => $uid,
"PWD" => $pwd
);
$conn = sqlsrv_connect($server, $cinfo);
if ($conn === false) {
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
// Test input
$from = (new DateTime('2020-07-02'))->format('Ymd');
$to = (new DateTime('2020-07-03'))->format('Ymd');
// Statement
$sql = "
SELECT *
FROM Database
WHERE (? <= [Date]) AND ([Date] <= ?)"
;
$params = array($from, $to);
$stmt = sqlsrv_query($conn, $sql, $params);
if($stmt == false){
die( print_r( sqlsrv_errors(), true) );
}
echo $sql;
// Data
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC) ) {
echo $row[0].", ".$row[1]."<br />";
}
// End
sqlsrv_free_stmt($stmt);
?>
Example, based on the code in the question, using PHP date objects and the appropriate parameters bindings:
<?php
// Connection
$server = 'server,port';
$database = 'database';
$uid = 'uid';
$pwd = 'pwd';
$cinfo = array(
"ReturnDatesAsStrings" => true,
"Database" => $database,
"UID" => $uid,
"PWD" => $pwd
);
$conn = sqlsrv_connect($server, $cinfo);
if ($conn === false) {
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
// Test input
$from = new DateTime('2020-07-02');
$to = new DateTime('2020-07-03');
// Statement
$sql = "
SELECT *
FROM Database
WHERE (CONVERT(date, ?) <= [Date]) AND ([Date] <= CONVERT(date, ?))"
;
$params = array(
array($from, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_DATETIME, SQLSRV_SQLTYPE_DATETIME),
array($to, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_DATETIME, SQLSRV_SQLTYPE_DATETIME)
);
$stmt = sqlsrv_query($conn, $sql, $params);
if($stmt == false){
die( print_r( sqlsrv_errors(), true) );
}
echo $sql;
// Data
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC) ) {
echo $row[0].", ".$row[1]."<br />";
}
// End
sqlsrv_free_stmt($stmt);
?>

Related

sql update multiple column in a foreach loop using prepared statement

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);
?>

Executing stored procedure in php laravel

I am using Laravel 7 and I want to show the results from the stored procedure. My code is given below. When I execute the stored procedure with parameters in SQL Server, it's showing data. But in Laravel application data is not showing.
Please, help me to find the problem.
$serverName = env("DB_HOST");
$connectionInfo = array( "Database"=>env("DB_DATABASE"), "UID"=>env("DB_USERNAME"), "PWD"=>env("DB_PASSWORD") );
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false ) {
die( print_r( sqlsrv_errors(), true));
}
$tsql= " EXEC USP_Daily_TA_Punching_Detailswith_OT '$employee','$datefrom','$dateto'";
$getResults= sqlsrv_query($conn, $tsql);
$data = array();
if ($getResults == FALSE)
{
echo '';
}
else {
//$data[] ='';
do
{
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC))
{
$data[] = $row;
}
}
while (sqlsrv_next_result($getResults));
}
if(count($data)>0){
sqlsrv_free_stmt($getResults);
$total_row = count($data);
}
Always try to use parameters in your statements to prevent possible SQL injection issues. As an additional note, use unambiguous date format, when you pass date values to SQL Server:
Example using PHP Driver for SQL Server:
<?php
// Connection
$serverName = env("DB_HOST");
$connectionInfo = array(
"Database"=>env("DB_DATABASE"),
"UID"=>env("DB_USERNAME"),
"PWD"=>env("DB_PASSWORD")
);
$conn = sqlsrv_connect($serverName, $connectionInfo);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
// Statement
$employee = '000010993';
$datefrom = '20200601';
$dateto = '20200610';
$tsql = "EXEC USP_Daily_TA_Punching_Detailswith_OT ?, ?, ?";
$params = array($employee, $datefrom, $dateto);
$getResults = sqlsrv_query($conn, $tsql, $params);
if ($getResults === false) {
die(print_r(sqlsrv_errors(), true));
}
// Results
$data = array();
do {
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
$data[] = $row;
}
} while (sqlsrv_next_result($getResults));
// End
sqlsrv_free_stmt($getResults);
sqlsrv_close($conn);
$total_row = count($data);
?>
Example using Laravel:
<?php
...
$employee = '000010993';
$datefrom = '20200601';
$dateto = '20200610';
DB::select("SET NOCOUNT ON; EXEC USP_Daily_TA_Punching_Detailswith_OT ?, ?, ?", array($employee, $datefrom, $dateto));
...
?>
Try the below to call the store procedure in laravel
DB::select("call USP_Daily_TA_Punching_Detailswith_OT('".$employee."','".$datefrom."','".$dateto."')");

Exec SQL Server stored procedure from PHP

I tried to call a SQL Server stored procedure from PHP.
Here is my stored procedure:
CREATE procedure [dbo].[tester]
#id NVARCHAR(MAX)
AS
BEGIN
DECLARE #tab TABLE (myxml XML)
INSERT INTO #tab(myxml)
SELECT map
FROM forms
WHERE mapid = #id
SELECT * FROM #tab
END
and my PHP script:
<?php
$serverName = "servername";
$connectionInfo = array("UID" => "sa","PWD" => "mypass","Database" => "database");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if ($conn) {
$tsql = "exec tester 'FORMgRGVL7bfpEnpBpg7vz2sHoKAs5zxU5LW'";
$result = sqlsrv_query($conn, $tsql);
if ($result === false) {
die( print_r( sqlsrv_errors(), true) );
$response=array('response'=>'notok','data'=>'loyo');
$serverresponse=JSON_encode($response);
} else {
$row = sqlsrv_fetch_array( $result, SQLSRV_FETCH_NUMERIC);
$response=array('response'=>'ok','data'=>$row[0]);
$serverresponse=JSON_encode($response);
}
sqlsrv_free_stmt($stmt);
} else {
$response=array('response'=>'notok','flag'=>$flag,'data'=>'cc');
$serverresponse = $serverresponse=JSON_encode($response);
}
echo ($serverresponse);
?>
When I execute the stored procedure from SSMS it returns the value as expected, but when I execute it from PHP, it returns null.
Explanations:
You need to put SET NOCOUNT ON as first line in your stored procedure to prevent returning the number of rows affected by the T-SQL statements as part of the result set. This is the reason for your NULL results.
As a note, always use prepared statements and parameterized queries to prevent SQL injection. With PHP Driver for SQL Server, function sqlsrv_query() does both statement preparation and statement execution and can be used to execute parameterized queries.
Example:
There are errors in your script, which are fixed in the example:
sqlsrv_free_stmt($stmt) is changed to sqlsrv_free_stmt($result)
variable $flag is not defined
$serverresponse = $serverresponse=JSON_encode($response) is changed to $serverresponse = json_encode($response)
T-SQL:
CREATE procedure [dbo].[tester]
#id nvarchar(max)
as
begin
SET NOCOUNT ON
declare #tab table (myxml xml)
insert into #tab(myxml)
select map from forms where mapid=#id
select * from #tab
end
PHP:
<?php
$flag = "";
$serverName = "servername";
$connectionInfo = array("UID" => "sa", "PWD" => "mypass", "Database" => "database");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if ($conn) {
$tsql = "exec tester ?";
$params = array('FORMgRGVL7bfpEnpBpg7vz2sHoKAs5zxU5LW');
$result = sqlsrv_query($conn, $tsql, $params);
if ($result === false) {
die( print_r( sqlsrv_errors(), true) );
$response = array('response'=>'notok', 'data'=>'loyo');
$serverresponse = json_encode($response);
} else {
$row = sqlsrv_fetch_array( $result, SQLSRV_FETCH_NUMERIC);
$response = array('response'=>'ok', 'data'=>$row[0]);
$serverresponse = json_encode($response);
}
sqlsrv_free_stmt($result);
} else {
$response = array('response'=>'notok', 'flag'=>$flag, 'data'=>'cc');
$serverresponse = json_encode($response);
}
echo ($serverresponse);
?>

Parameterized Query PHP/SQL Server

I have a web form that enters event details into a database to be listed on a website. The form captures the name of a photo, event title, a date to unlist the event, a sort number, a description, and a bit flag "Mass".
The description field is a plain text field. I know that I should probably change the field to rich text, but that is for a day when I have time to explore how to do that. Anyways... I've been adding HTML characters into my text to format it. I find that the slash of closing characters like < / strong> is being treated as an escape character rather than part of the text. How do I tell my code to not escape?
The code:
//connect to the database.
$serverName = "livedata";
$connectionInfo = array( "Database"=>"administration", "UID"=>"User", "PWD"=>"PASSWORD", "LoginTimeout"=>60 );
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false ) {
die( print_r( sqlsrv_errors(), true));
}
/* Set up the parameterized query. */
$tsql = "insert into tblevents (Photo, title, Unlist, Sort, Description, Par_num, mass ) values(?,?,?,?,?,?,?)";
/* Set parameter values. */
$dt = $_POST['unlist'];
if ($dt == ""){
$dt = null;
}
$Sort = $_POST['sort'];
if ($Sort == "" ){
//query to get the max of sort in the database items
//+1 sort
$sql2 = "SELECT tblevents.Par_Num, Max(tblevents.Sort) AS MaxOfSort FROM parishevents.dbo.tblevents GROUP BY tblevents.Par_Num HAVING (((tblevents.Par_Num)=" . $_POST['par_num'] . "));";
//echo "SQL2: " . $sql2 . "<br><br>";
$stmt2 = sqlsrv_query( $conn, $sql2);
if( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true));
}
$result2 = sqlsrv_query($conn, $sql2);
while($row2 = sqlsrv_fetch_array($result2)) {
$Sort = $row2['MaxOfSort'] +1;
}
if(isset($_POST['mass'])){
if($_POST['mass'] == "on"){
$mass = -1;
}
else{
$mass = 0;
}
}else{
$mass = 0;
}
$params = array($_POST['photo'], $_POST['title'], $dt, $Sort, $_POST['description'], $_POST['par_num'], $mass);
/* Prepare and execute the query. */
$stmt = sqlsrv_query($conn, $tsql, $params);
/* Free statement and connection resources. */
sqlsrv_free_stmt($stmt);
}

PHP get return value of stored procedure

I have pleasure to work with legacy PHP application using SQL Server via PDO.
How in PHP can I retrieve return value of stored procedure which is using RETURN statement as output channel?
Example procedure
CREATE PROCEDURE [dbo].[mleko_test]
#param INT
AS
BEGIN
RETURN #param * 3;
END
GO
If possible, I would prefer to not modify procedure.
I am aware that there are similar questions, but they don't cover this case
Get RETURN value from stored procedure in SQL
Get Return Value from SQL Stored Procedure using PHP
Execute stored procedure like this: "exec ?=mleko_test(?)".
Working example:
<?php
#------------------------------
# Connection info
#------------------------------
$server = 'server\instance,port';
$database = 'database';
$uid = 'user';
$pwd = 'password';
#------------------------------
# With PDO
#------------------------------
try {
$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch ( PDOException $e ) {
die ( "Error connecting to SQL Server" );
}
try {
$sql = "exec ? = mleko_test (?)";
$param = 3;
$spresult = 0;
$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $spresult, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
$stmt->bindParam(2, $param);
$stmt->execute();
} catch ( PDOException $e ) {
die ( "Error connecting to SQL Server" );
}
$stmt = null;
$conn = null;
echo 'Stored procedure return value (with PDO): '.$spresult."</br>";
#------------------------------
# Without PDO
#------------------------------
$cinfo = array (
"Database" => $database,
"UID" => $uid,
"PWD" => $pwd
);
$conn = sqlsrv_connect($server, $cinfo);
if ( $conn === false )
{
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
$sql = "exec ? = mleko_test (?)";
$param = 3;
$spresult = 0;
$params = array(
array(&$spresult, SQLSRV_PARAM_OUT),
array($param, SQLSRV_PARAM_IN),
);
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
exit;
}
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
echo 'Stored procedure return value (without PDO): '.$spresult."</br>";
?>
Notes:
Tested with PHP 7.1.12 and PHP Driver for SQL Server (pdo_sqlsrv version 4.3.0+9904).
I came to a solution using multi-query but #Zhorov answer is cleaner
<?php
$connection = new PDO($connectionString, $DB_USERNAME, $DB_PASSWORD);
$stmt = $connection->prepare(<<<SQL
DECLARE #a INT;
EXEC #a = mleko_test :in
SELECT #a AS result;
SQL
);
$stmt->execute([":in" => 123]);
echo $stmt->fetch()["result"] . "\n";
I had to change
$sql = "exec ?=mleko_test(?)";
for
$sql = "{?=call mleko_test(?)}";

Categories