PHP PDO未从MSSQL存储过程调用中找到输出参数

PHP PDO未从MSSQL存储过程调用中找到输出参数,php,sql-server,pdo,io,Php,Sql Server,Pdo,Io,我已经在这方面工作了3天,并尝试了在这3天中我能找到的所有可能的示例说明。我必须寻求帮助,以试图理解这里与输出参数有关的哪些功能不起作用。这是一种机器对机器的操作,没有终端或网页人机交互,只存在于内部私有子网中。调用者-->Cisco IVR-->PHP-->MSSQL DB-->PHP-->Cisco IVR-->调用者。我已经包括了我的整个PHP工作脚本,但我想重点讨论为什么我的parameter 3语句不起作用。我的MSSQL存储过程代码是1 ALTER PROCEDURE [dbo].[

我已经在这方面工作了3天,并尝试了在这3天中我能找到的所有可能的示例说明。我必须寻求帮助,以试图理解这里与输出参数有关的哪些功能不起作用。这是一种机器对机器的操作,没有终端或网页人机交互,只存在于内部私有子网中。调用者-->Cisco IVR-->PHP-->MSSQL DB-->PHP-->Cisco IVR-->调用者。我已经包括了我的整个PHP工作脚本,但我想重点讨论为什么我的parameter 3语句不起作用。我的MSSQL存储过程代码是1

ALTER PROCEDURE [dbo].[pIOGetEligSSNDOB]
    
    @SSN NVARCHAR(9),
    @DOB NVARCHAR(8),
    @RCODE INT OUTPUT 
    
AS
BEGIN   

    SELECT * FROM ZASMasterDB.dbo.Eligibility WHERE SSN = @SSN AND DOB = @DOB
    IF @@ROWCOUNT >= 1
    SET @RCODE = 3
    ELSE 
    SET @RCODE = 5
       SELECT 'ReturnCode' = @RCODE
       RETURN @RCODE
       
END


****My working PHP version 7.4.10 script using PDO****


$ID = $_GET['MEMBER_ID']; $DOB = $_GET['DOB'];
$start_time             = microtime(true);

$sth = $pdo->prepare("exec dbo.pIOGetEligSSNDOB ?, ?, ? "); // I am using 2 INPUT and 1 OUTPUT

$RCODE = 0;
$row_count = 0;

$sth->bindParam(1, $ID);     // Members social security number as INPUT to SQL server
$sth->bindParam(2, $DOB);    // Members date of birth as INPUT to SQL server
$sth->bindParam(3, $RCODE, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT,10); //$RCODE to hold the OUTPUT integer 

$sth->execute();
    
$time                   = round( (microtime(true) - $start_time), 4);           
$col_count              = 0;

//ARRAYS TO HELP ORGANIZE THE RESULTS
$column_name_array      = array();
$rows_array             = array();

// THE LOOP!

while($row = $sth->fetch(PDO::FETCH_ASSOC)){
    
    $row_count++;                         // A MUST for the IVR to know how many records returned 
    $col_count          = count($row);
    $column_name_array  = array_keys($row); 
    $row = array_map('trim',$row);      
    $rows_array[]       = join("·", array_values($row));  //Delineation for the IVR
} 

    $sth = null;       
    $pdo = null;
 
 
?>   


<response>
    <time><?=$time?></time>
    <cols><?=$col_count?></cols>
    <rows><?=$row_count?></rows>
    <code><?=$RCODE?></code>          // This should be the value of the OUTPUT parameter from SQL DB
    <column_names>
    <?=join("·", $column_name_array)?>   
    </column_names>
    <data>
    <?=join("·", $rows_array)?>·                                                     
    </data>
</response>
仍然没有返回值,但PHP没有抱怨,仍然返回了我的常规数据。我试图在准备行中使用与在SQL mgt studio中手动使用完全相同的东西

 $sth = $pdo->prepare("DECLARE @RCODE INT; exec pIOGetEligSSNDOB ?,?, @RCODE = @RCODE OUTPUT;");
并且没有$RCODE结果

所以,几天前我在拔头发的时候读到了整个“nextRowset”的事情,但是当我还在努力让它工作的时候,就忘了它。谢谢你提醒我Zhorov!!。因此,我将do添加到我的原始while中,然后在所有do的末尾添加while,就像在这些示例中一样

do {
    while($row = $sth->fetch(PDO::FETCH_ASSOC)){

    $row_count++;
    $col_count          = count($row);

    $column_name_array  = array_keys($row); 
    
    $row = array_map('trim',$row);      
    
    $rows_array[]       = join("·", array_values($row));
} 
}  while ($sth->nextRowset());  
现在,我的最终XML输出有点不同,我确实看到了整数7,但它被添加到了常规数据获取结果的末尾,而不是我需要它的地方,即代码元素之间。然后,它不再显示通常在列名元素之间显示的所有常规列名,而是显示了我不想看到的名称“ReturnCode”。所以我现在肯定有格式问题。我确实遵循了nextRowset代码的示例,与前面解释的完全相同,但最终输出中出现了一些错误。这是非常困难的,当你仍然试图学习PHP,不太了解所有东西的位置和语法,但我现在比以前更接近

所以我相信我在这里解决了我自己的问题。当PHP首先执行返回预期结果集的MSSQL存储过程时,我用于PHP PDO代码的“免费TDS驱动程序”似乎不支持使用MSSQL的输出参数。我找到的支持此功能的注释就在堆栈上,但是这些注释中解释为什么不支持输出参数的链接说Microsoft在MSSQL版本7及更高版本中删除了输出参数?我想Ver7是1998年推出的。我不知道这部分是否正确,但我可以向你保证,在我这里的问题中,输出参数根本不起作用。因此,另一种选择是在PHP中使用nextRowset命令,但不是以许多示例所示的方式。我必须自己摸索,反复试验。我不需要一个do..while循环,我也不需要在原始循环结束时有一段时间。必须使SQL代码看起来像这样

CREATE PROCEDURE [dbo].[pIOGetEligSSDOB]
    
    @SSN nvarchar(10),
    @DOB nvarchar(10)   
    
AS
BEGIN
    DECLARE @RCODE int
    SELECT * FROM ZASMasterDB.dbo.Eligibility WHERE SSN = @SSN AND DOB = @DOB
    IF @@ROWCOUNT >= 1
    SET @RCODE = 7
    ELSE
    SET @RCODE = 8
       SELECT @RCODE      

END
然后在PHP中,我保持了原来的工作循环的原样,并在循环代码之后添加了两行代码。我首先必须像所有示例代码所示的那样前进到下一个strowset,但随后我必须进入下一行列,取出一位数的返回代码并将其放入$rcode中,以最终显示在
元素中的XML输出中

while($row = $sth->fetch(PDO::FETCH_ASSOC)){ $row_count++; $col_count = count($row); $column_name_array = array_keys($row); $row = array_map('trim',$row); $rows_array[] = join("·", array_values($row)); } $sth ->nextRowset(); $rcode = $sth->fetchColumn();
而($row=$sth->fetch(PDO::fetch_ASSOC)){ $row_count++; $col_count=计数($row); $column\u name\u array=array\u key($row); $row=数组映射($trim',$row); $rows_数组[]=连接(“·”,数组_值($row)); } $sth->nextRowset(); $rcode=$sth->fetchColumn(); 因此,最终输出如下所示:


我们遇到了同样的问题,SP打算通过PDO调用返回3个out参数,从而对sql server产生副作用:

不确定这是否有帮助,但您可以尝试在调用SQL Server过程之前使用“SET NOCOUNT ON;”语句作为前缀

或开始和结束Transact-sql strored过程 不计数; ... 不计数

可能对你有用。。。或者,如果SP调用的额外过程中未正确设置这些标志,则不会


我们仍在寻找更好的解决方案…

鉴于SQL Server中的
int
是32位/4字节,您是否尝试过在
bindParam
中使用length
4
而不是length
10
?您是否也尝试过类似
$pdo->prepare(“exec dbo.piogetligsndob?,?,?output”)
? while($row = $sth->fetch(PDO::FETCH_ASSOC)){ $row_count++; $col_count = count($row); $column_name_array = array_keys($row); $row = array_map('trim',$row); $rows_array[] = join("·", array_values($row)); } $sth ->nextRowset(); $rcode = $sth->fetchColumn();