簡體   English   中英

帶有 INOUT 參數的 PHP PDO 存儲過程不更新值

[英]PHP PDO stored procedure with INOUT parameter not updating value

我有以下 PostgreSQL (14.6) 存儲過程:

CREATE OR REPLACE PROCEDURE business_layer_thick_db.outtest
   ( IN OUT  p_test  VARCHAR
   )
LANGUAGE plpgsql
AS
$PROC$
   BEGIN
      p_test := 'New value!';
   END;
$PROC$

當我在 dBeaver 中運行以下匿名 PLpg/SQL 時:

do
$$
declare
   v_test  varchar  := 'Old value!';
begin
   raise notice '%', v_test;
   CALL business_layer_thick_db.outtest (p_test => v_test);
   raise notice '%', v_test;
end;
$$

...我得到以下輸出:

舊值! 新價值!

當我運行以下 PHP (8.1) 代碼時:

<?php
   // Report all errors
   ini_set ('display_errors', 1);
   ini_set ('display_startup_errors', 1);
   error_reporting (E_ALL);
   
   // Create PDO DB connection
   $v_user     = <<redacted>>;
   $v_password = <<redacted>>;
   $v_dsn      = "pgsql:host=<<redacted>>;port=5432;dbname=<<redacted>>;user=$v_user;password=$v_password";
   $v_options  =  [  PDO::ATTR_ERRMODE             => PDO::ERRMODE_EXCEPTION,
                     PDO::ATTR_DEFAULT_FETCH_MODE  => PDO::FETCH_ASSOC,
                     PDO::ATTR_EMULATE_PREPARES    => false,
                     PDO::ATTR_ORACLE_NULLS        => PDO::NULL_EMPTY_STRING
                  ];

   try
   {
      $v_pdo = new PDO ($v_dsn, $v_user, $v_password, $v_options);
   }
   catch (\PDOException $v_exception)
   {
      throw new \PDOException ($v_exception->getMessage (), (int)$v_exception->getCode ());
   }

   $v_test = "Old value!";

   echo $v_test . "<br />";

   $v_stmt = $v_pdo->prepare ("CALL business_layer_thick_db.outtest (p_test => :v_test)");
   $v_stmt->bindParam (":v_test", $v_test, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 32767);
   $v_stmt->execute ();

   echo $v_test . "<br />";
?>

我得到以下輸出:

舊值! 舊值!

我看不出我哪里出錯了。 非常感謝您的建議。 顯然,我希望兩者的輸出都是:

舊值! 新價值!

參數綁定的設置顯然有問題。

因此,我對此的研究強烈表明存在導致 PDO::PARAM_INPUT_OUTPUT無法工作的錯誤。 盡管它存在已久,但從未得到修復。

https://bugs.php.net/bug.php?id=43887 https://bugs.php.net/bug.php?id=46657 PDO::PARAM_INPUT_OUTPUT 在 PostgreSQL 中不工作?

但是,有一個解決方法。

從上面的 PHP 8.1 代碼的第 26 行,改為執行以下操作:

   $v_test = "Old value!";

   echo $v_test . "<br />";

   $v_stmt = $v_pdo->prepare ("CALL business_layer_thick_db.outtest (:v_test)");
   $v_stmt->bindParam ("v_test", $v_test, PDO::PARAM_STR, 4000);
   $v_stmt->execute ();

   $v_test = $v_stmt->fetch ();

   echo var_dump ($v_test) . "<br />";

這不一定是最佳方法,但至少證明可以使用 PDOStatement::fetch() 獲取 INOUT 和 OUT 參數。

暫無
暫無

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

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