使用PHP PDO获取MSSQL存储的Proc结果

时间:2015-01-08 18:27:26

标签: php sql-server pdo

我在MSSQL 2008 R2中有一个相当复杂的存储过程,最终导致返回一个小表。 PHP将从javascript中调用,我希望它将数组作为JSON返回,以便在javascript中的表中使用。

我正在使用PHP来访问它,并且使用分析器可以看到我正在调用SP并将正确的参数传递给它。

我的PHP看起来像这样:

try {
    $dbh = new PDO("sqlsrv:Server=(local);Database=cddDispo");
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo json_encode("Error connecting to the server.");
    die ();
}

$lot = $_POST["lot-input"];
$layerAdder = $_POST["layer-input"];

$adder = substr($layerAdder,-3,3);
$adder = str_replace('=','',$adder);
$layer = substr($layerAdder,0,strpos($layerAdder,' '));

$sth = $dbh->prepare('EXEC dbo.pullDispo ?,?,?');

$sth->bindParam(1,$lot,PDO::PARAM_STR);
$sth->bindParam(2,$layer,PDO::PARAM_STR);
$sth->bindParam(3,$adder,PDO::PARAM_STR);

$array = array();

try {
    $sth->execute();

    while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
        //I want to build my output array here
   }
}catch (PDOException $e) {
    echo "Error getting data, please try again.";
    die();
}

header('Content-type: application/json');
echo json_encode($array);

这是我第一次尝试从存储过程返回表结果,甚至还有几个PHP Manual / Google搜索我还没弄清楚如何在PHP中捕获表。我有一个不太优雅的解决方法(将SP表写入静态表并稍后在PHP中调用该表)但更愿意弄清楚我是否可以以更优雅的方式进行操作。任何建议都非常感谢。

我认为如果我发布最终代码可能会有用:

function array_push_assoc($array,$key,$value) {
    $array[$key] = $value;
    return $array;
}

header('Content-type: application/json');

try {
    $dbh = new PDO('sqlsrv:Server=(local);Database=cddDispo');
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo json_encode('Error connecting to the server.');
    die ();
}

$lot = $_POST['lot'];
$layer = $_POST['layer'];
$adder = $_POST['adder'];

$sth = $dbh->prepare('EXEC dbo.pullDispo ?,?,?');

$sth->bindParam(1,$lot,PDO::PARAM_STR);
$sth->bindParam(2,$layer,PDO::PARAM_STR);
$sth->bindParam(3,$adder,PDO::PARAM_STR);

$results = array();
$combinedArray = array();
$array = array();
$count = 0;

try {
    $sth->execute();
    do {
        $results[] = $sth->fetchAll(PDO::FETCH_ASSOC);
    }while ($sth->nextRowset());

    foreach($results as $row) {
        if($count == 0) {
            $headerArray =
                [
                    'Lot'               =>$row['Lot'],
                    'Layer'             =>$row['Measured Layer'],
                    'Product'           =>$row['MES Product'],
                    'Adder'             =>$row['Adder Chart']
                ];
            $combinedArray = array_push_assoc($combinedArray,'header',$headerArray);
        }

        $count++;

        //This is for formatting of final table
        if($row['UDL'] == 0) {
            $udl = 'NA';
        } else {
            $udl = round($row['UDL'],4);
        }

        $infoArray =
            [
                'Wafer'             =>$row['Wafer'],
                'Type'              =>$row['Type'],
                'Count'             =>$row['Count'],
                'CDD'               =>round($row['CDD'],3),
                'UCL'               =>round($row['UCL'],4)
            ];
        array_push($array,$infoArray);
    }
    $combinedArray = array_push_assoc($combinedArray,'detail',$array);
}catch (PDOException $e) {
    echo json_encode('Error running stored procedure.');
    die();
}

echo json_encode($combinedArray);

3 个答案:

答案 0 :(得分:1)

您的存储过程是否会返回多个结果集?这包括警告消息或受影响的行数等输出。尝试在SET ANSI_WARNINGS OFF之后的存储过程顶部添加SET NOCOUNT ONAS。在尝试通过$stg->nextRowset()之前调用$sth->fetchAll()来获取结果之前,您还可以尝试前进到PHP中的下一个结果集。

答案 1 :(得分:0)

使用fetchAll()获取结果集,然后将该数组编码为json响应:

$array = array();
try {
    if($sth->execute()){
        $array = $sth->fetchAll(PDO::FETCH_ASSOC);
    }else{
        $array = array('error'=>'failed to execute()')
    }
}catch (PDOException $e) {
    echo "Error getting data, please try again.";
    die();
}
header('Content-type: application/json');
echo json_encode($array);

答案 2 :(得分:0)

当您调用具有多个结果集的存储过程时,您可能不希望将SET NOCOUNT ON添加到您拥有的每个过程中;你总是可以添加

$dbh->setAttribute(constant('PDO::SQLSRV_ATTR_DIRECT_QUERY'), true);
$dbh->query("SET NOCOUNT ON"); 

之前的

$dbh->prepare($query);

它会起作用。