簡體   English   中英

如何從laravel的mysql存儲過程中獲取多個結果集

[英]how to fetch multiple result set from a mysql stored procedure in laravel

我想從 laravel 的存儲過程中獲取多個結果集。 有沒有辦法做到這一點? 目前,我可以使用以下代碼獲取單行數據:

$result = DB::statement('CALL user_login(' . $userId . ',"'
                                                              . $password . '",'
                                                              . '@success'.','
                                                              . '@first_Name'
                                                              );

$res = DB::select('select @success AS success, @first_Name AS firstName);

Here is my stored procedure:

DELIMITER //

DROP PROCEDURE IF EXISTS user_login//

create procedure user_login (IN userid VARCHAR(50),
                                   IN password VARCHAR(50),
                                   out success int,
                                   OUT first_Name VARCHAR(255),
                                   )

begin

declare count int(1);
set count =0;

select firstName, count(*)
into first_Name, count
from `tmc`.user where user_id = userid and pwd=password;

if count >0 then

set success =0;

else 
set success=1;

end if;

end//

我正在使用以下代碼,它可以完美運行。 更改它以滿足您的需求。

public static function CallRaw($procName, $parameters = null, $isExecute = false)
{
    $syntax = '';
    for ($i = 0; $i < count($parameters); $i++) {
        $syntax .= (!empty($syntax) ? ',' : '') . '?';
    }
    $syntax = 'CALL ' . $procName . '(' . $syntax . ');';

    $pdo = DB::connection()->getPdo();
    $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
    $stmt = $pdo->prepare($syntax,[\PDO::ATTR_CURSOR=>\PDO::CURSOR_SCROLL]);
    for ($i = 0; $i < count($parameters); $i++) {
        $stmt->bindValue((1 + $i), $parameters[$i]);
    }
    $exec = $stmt->execute();
    if (!$exec) return $pdo->errorInfo();
    if ($isExecute) return $exec;

    $results = [];
    do {
        try {
            $results[] = $stmt->fetchAll(\PDO::FETCH_OBJ);
        } catch (\Exception $ex) {

        }
    } while ($stmt->nextRowset());


    if (1 === count($results)) return $results[0];
    return $results;
}

示例調用:

$params = ['2014-01-01','2014-12-31',100];
$results = APIDB::CallRaw('spGetData',$params);

結果調用將是:

CALL spGetData(?,?,?)

如果只有一個結果集,它將按原樣返回。 如果有更多,它將返回一個結果集數組。 關鍵是使用$pdo->setAttribute(\\PDO::ATTR_EMULATE_PREPARES, true); . 沒有它,會拋出一個可怕的SQLSTATE[HY000]: General error: 2053異常。

try{} catch() 塊用於消除無法獲取的結果集。 特別是,我有返回兩個結果集的過程,一個作為更新(或其他執行語句)的結果,最后一個作為真實數據。 使用執行查詢在fetchAll()上拋出的異常將是PDOException

警告:該功能未優化。 您可以通過一次傳遞參數來重寫它。

如果您的存儲過程返回多個輸出,在這種情況下,您可以通過兩種方法處理這種情況。

  1. 轉到vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connectors\\Connector.php並將PDO::ATTR_EMULATE_PREPARES設置為true

當您開發 API 時會產生問題,因為當響應以 JSON 形式返回時,所有 API 都以字符串形式返回數字,例如: {"status": "1"}但它應該是{"status": 1}

  1. 為特定情況添加新連接。 您必須僅針對特定 API 處理上述問題,而不是在所有 API 中。 所以我建議選擇選項2。

config/database.php添加連接使用下面的代碼到connections

'mysql_procedure' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => 'sv_',
'prefix_indexes' => true,
'strict' => false,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),PDO::ATTR_EMULATE_PREPARES => true
]) : [],
],

根據您的配置更新詳細信息。

$procRslts = DB::connection('mysql_procedure')
->select("CALL user_login(?,?,?,?)", array( $userId ,$password,$success,$firstName ));

我認為在這個你不需要傳遞最后兩個參數,你可以編寫邏輯int過程來從數據庫中獲取。

您可以獲得存儲過程返回的多個輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM