I have a problem executing the SQL Server Stored Procedures from php PDO:
If parameters in $SQL are not in the same order sequence of the parameters in the Stored Procedure, values are not passed to the correspondent parameter but just to the next in the list:
here an example:
<?php
$hostname = '';
$database = '';
$user = '';
$password = '';
$DB = new PDO("sqlsrv:Server=".$hostname.";Database=".$database.";TransactionIsolation=".PDO::SQLSRV_TXN_READ_UNCOMMITTED, $user, $password);
$p1='p1';
$p2='p2';
$p3='p3';
$SQL="EXEC dbo.sp__TEST :p1,:p2,:p3";
$rsx= $DB->prepare($SQL,[PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]);
$rsx->bindParam(':p1',$p1, PDO::PARAM_STR);
$rsx->bindParam(':p3',$p3, PDO::PARAM_STR);
$rsx->bindParam(':p2',$p2, PDO::PARAM_STR);
$rsx->execute();
$res=$rsx->fetch(PDO::FETCH_ASSOC);
echo '<br>'.$res['result'];
?>
and here the SQL Server sproc:
CREATE PROCEDURE dbo.sp__TEST
(
@p1 nvarchar(65)='',
@p2 nvarchar(65)='',
@p3 nvarchar(65)=''
)
AS
SET NOCOUNT ON;
BEGIN
declare @p4 nvarchar(65)
set @p4='p1=>'+@p1+'<br>p2=>'+@p2+'<br>p3=>'+@p3
select @p4 as result
END
SET NOCOUNT OFF;
Here we will have as output:
p1=>p1
p2=>p2
p3=>p3
but if we change the $SQL declaration as follows:
$SQL="EXEC dbo.sp__TEST :p1,:p3";
we will have the following output:
p1=>p1
p2=>p3
p3=>
while I would expect to get
p1=>p1
p2=>
p3=>p3
This means that if I need to change/add/remove some parameters I have always to check if are in right sequence and is a waste of time..
Am I forgetting something or...
Thanks
TO THE UNWISE WHO DOWNVOTE: IF YOU CHANGE THE DECLARATION TO
$SQL="EXEC dbo.sp__TEST :p1,:p3,:p2";
YOU WILL GET AS RESULT:
p1=>p1
p2=>p3
p3=>p2
THAT IS NOT CORRECT:
MOREOVER, IF YOU CALL THE STORED PROCEDURE IN OTHER LANGUAGES (ASP, ASP.NET) IT RETURNS THE RIGHT RESULT EVEN IF YOU SHUFFLE THE PARAMETERS OR IF YOU OMIT SOME OF THEM.
ASP EXAMPLE
<%
dim cn,cst,cmd,p1,p2,p3,rsx
set cn=Server.CreateObject("ADODB.Connection")
cst="Provider=sqloledb;server=XXXXX;Database=yyyyy;User ID=sa;Password=zzzzz"
cn.CursorLocation = 3
cn.open cst
set cmd=Server.CreateObject("ADODB.Command")
set cmd.ActiveConnection= cn
p1="p1"
p2="p2"
p3="p3"
cmd.CommandText="dbo.sp__TEST"
cmd.CommandType=4 'adCmdStoredProc
cmd.Parameters("@p1")= p1
cmd.Parameters("@p2")= p2
cmd.Parameters("@p3")= p3
set rsx=cmd.execute()
if not rsx.eof then
response.write rsx("result")
end if
%>
This has nothing to do with PHP.
Your procedure declaration states that it accepts 3 paramteters:
CREATE PROCEDURE dbo.sp__TEST
(
@p1 nvarchar(65)='',
@p2 nvarchar(65)='',
@p3 nvarchar(65)=''
)
but your execution is only supplying 2:
$SQL="EXEC dbo.sp__TEST :p1,:p3"; // This is only supplying the first two parameters to your procedure
You would get the same result if you manually did:
$SQL="EXEC dbo.sp__TEST 'hi!','hey!'"; // This is only supplying the first two parameters to your procedure
You need to bind :p2
as an empty string to produce your expected result.