phpsql-serverlaravelstored-procedureslaravel-api

In Php, while calling a parametrized SQL Server stored procedures, how to get data from output parameters?


In Laravel 10, I'm using raw PHP code to call an as my stored procedure is returning 2 tables.

But I'm not able to receive the output parameters in either way. Is there any way to get the output parameters?

Code :

public function login(Request $request)
{
  $outputParam = "null";
  $outputParam2 = "null";
  $conn = DB::connection('sqlsrv');

  $sql =  Db::select('SET NOCOUNT ON; EXEC sp_Login  ' . $outputParam . ',' . $outputParam2.',Login,GetAll_for_login,null,admin,55e01f2a13f587e1e9e4aedb8242d,null, null, null, null, null, null, null, null, null, null, null, null, null, null;'); //,  array($request->in1, $request->in2)); 

  // I'm sending login details as hard coded for testing.
  $pdo = $conn->getPdo()->prepare($sql);
  $pdo->execute();
  $rows = array();
  $res = array();
  
  // Iterate through the recordsets
  do {
     $rows = $pdo->fetchAll();
     array_push($res, $rows);
  } while ($pdo->nextRowset());

  $data = $res[0];
  $data2 = $res[1];

  return $this->sendResponse('Done', ['maindata' => $res, "param1"  => $outputParam, "param2" => $outputParam2]);

  //return $this->sendResponse('Done', ['data' => $data, 'data2' => $data2]);
}

Below is the data I'm receiving in Postman after calling the function in API:

{
    "success": true,
    "data": "Done",
    "message": {
        "data": [
            [
                {
                   // Data from First Table
                }
            ],
            [
                {
                    // Data from Second Table
                }, 
            ]
        ],
        "param1": "null",
        "param2": "null"
    }
}

I previously tried to pass this way , but it was showing syntax error :

$sql = "SET NOCOUNT ON ; EXEC sp_Login 
        @pSuccessFlag = " . $outputParam . " ,
        @pMessage = " . $outputParam2 . " ,
        @pCallingPage = Login,
        @pOperation = GetAll_for_login,
        @pid = " . null . ",
        @puname = admin,
        @ppassword = c12e01f2a13ff5587e1e9e4aedb8242d,
        @premark = " . null . ",
        @POpwd = " . null . ",
        @PROLE_ID = " . null . ",
        @PIS_ACTIVE = " . null . ",
        @POTP = " . null . ",
        @POTP_DATE " . null . ",
        @PFACILITY_ID = " . null . ", 
        @PCREATED_BY = " . null . ", 
        @PCREATED_ON = " . null . ", 
        @PMODIFIED_BY = " . null . ", 
        @PMODIFIED_ON = " . null . ", 
        @PUSER_TYPE_ID = " . null . ", 
        @PEMP_ID = " . null . ", 
        @PSERVER_LOGTIME = " . null . ";";
        $pdo = $conn->getPdo()->prepare($sql);
        $pdo->execute();

Below are the datatype of my Parameters in my SP:

CREATE PROCEDURE "sp_Login"(
    IN "@pSuccessFlag" VARCHAR(2) OUTPUT,
    IN "@pMessage" VARCHAR(2000) OUTPUT,
    IN "@pCallingPage" VARCHAR(255),
    IN "@pOperation" VARCHAR(255),
    IN "@pid" int,
    IN "@puname" varchar(255),
    IN "@ppassword" varchar(50),
    IN "@premark" varchar(50),
    IN "@POpwd" varchar(50),
    IN "@PROLE_ID" int,
    IN "@PIS_ACTIVE" varchar(15),
    IN "@POTP" varchar(50),
    IN "@POTP_DATE" DATETIME,
    IN "@PFACILITY_ID" INT,
    IN "@PCREATED_BY" varchar(50),
    IN "@PCREATED_ON" DATETIME,
    IN "@PMODIFIED_BY" varchar(50),
    IN "@PMODIFIED_ON" DATETIME,
    IN "@PUSER_TYPE_ID" INT,
    IN "@PEMP_ID" INT,
    IN "@PSERVER_LOGTIME" DATETIME
)

Solution

  • You need to bind the output parameters (using PDOStatement::bindParam()), not to inject their values in the SQL statement. Include the data type and direction of each parameter (using the PDO::PARAM_* constants) and in case of an output parameter the length of the parameter.

    public function login(Request $request) {
    
        $outputParam  = "";
        $outputParam2 = "";
    
        $conn = DB::connection('sqlsrv');
        $sql = "
            SET NOCOUNT ON ;
            EXEC sp_Login 
                @pSuccessFlag = :outputParam,
                @pMessage = :outputParam2,
                @pCallingPage = 'Login',
                @pOperation = 'GetAll_for_login',
                @pid = NULL,
                @puname = 'admin',
                @ppassword = 'c12e01f2a13ff5587e1e9e4aedb8242d',
                @premark = NULL,
                @POpwd = NULL,
                @PROLE_ID = NULL,
                @PIS_ACTIVE = NULL,
                @POTP = NULL,
                @POTP_DATE = NULL,
                @PFACILITY_ID = NULL,
                @PCREATED_BY = NULL,
                @PCREATED_ON = NULL,
                @PMODIFIED_BY = NULL,
                @PMODIFIED_ON = NULL,
                @PUSER_TYPE_ID = NULL,
                @PEMP_ID = NULL,
                @PSERVER_LOGTIME = NULL;
        ";
        $pdo = $conn->getPdo()->prepare($sql);
        $pdo->bindParam(':outputParam',  $outputParam,  PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2);
        $pdo->bindParam(':outputParam2', $outputParam2, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2000);
        $pdo->execute();
    
        $result = array();
        do {
            $rows = $pdo->fetchAll();
            array_push($result, $rows);
        } while ($pdo->nextRowset());
    
        return $this->sendResponse('Done', ['maindata' => $result, "param1"  => $outputParam, "param2" => $outputParam2]);
    }