簡體   English   中英

在 pg_prepare/pg_execute 中使用 postgres 常量

[英]Use postgres constants with pg_prepare/pg_execute

假設這張表:

CREATE TABLE log
(
  user smallint NOT NULL,
  moment timestamp without time zone NOT NULL DEFAULT (clock_timestamp())::timestamp without time zone,
  details text NOT NULL,
  CONSTRAINT log_pk PRIMARY KEY (user, moment)
);

要向表中添加記錄,我將使用以下代碼:

<?php

  $dbconn = pg_connect('dbname=system');

  $query = <<<EOQ
INSERT INTO
  log
VALUES
  (
    $1,
    DEFAULT,
    $3
  )
EOQ;

// ...

使用“DEFAULT”常量作為第二個參數,但出於“一系列奇怪的原因”,我需要能夠像這樣運行它:

<?php

  $dbconn = pg_connect('dbname=system');

  $query = <<<EOQ
INSERT INTO
  log
VALUES
  (
    $1,
    $2,
    $3
  )
EOQ;

  $result = pg_prepare($dbconn, '', $query);

  $data=
    [
      10,
      'DEFAULT',
      'IP: 127.0.0.1'
    ];

  $result = pg_execute($dbconn, '', $data);

問題是,以這種方式,常量作為文本接收,php 引發錯誤“ PHP 警告:pg_execute():查詢失敗:錯誤:類型時間戳的無效輸入語法:“DEFAULT” ”。

有沒有辦法使用 postgres 常量作為 pg_prepare/pg_execute 的參數?

PS:我正在使用 php 8 和 postgres 13.4

編輯:

我也試過使用這種格式:


// ...

  $query = <<<EOQ
INSERT INTO
  acessos
VALUES
  (
    $1,
    CASE WHEN $2='DEFAULT' THEN
      DEFAULT
    ELSE
      $2
    END,
    $3
  )
EOQ;

// ...

但我收到另一條錯誤消息,“ PHP 警告:pg_prepare():查詢失敗:錯誤:在此上下文中不允許使用默認值”...

“奇怪原因的集合”需要一個奇怪的解決方案。 如果您必須提供 3 個參數但只使用 2 個,那么我建議更改查詢,以便它會默默地忽略第二個參數。

$query = <<<EOQ
INSERT INTO log
VALUES
(
 case when $2 is null or $2 is not null then $1 end, -- const.true but $2 is 'used'
 DEFAULT,
 $3
)
EOQ;

或者,更好的是,顯式使用默認表達式

$query = <<<EOQ
INSERT INTO
  acessos
VALUES
  (
    $1,
    CASE WHEN $2 ~* '^DEFAULT$' THEN clock_timestamp() ELSE $2::timestamp END,
    $3
  )
EOQ;

DEFAULT是一個 SQL 關鍵字,因此是 SQL 語句的一部分,您不能為其使用參數。 您必須在 PHP 代碼中使用兩種不同的INSERT語句,一種插入moment ,另一種不插入。

另一種方法是使用動態 SQL,但我認為那樣可讀性較差且更復雜(並且您必須小心避免 SQL 注入)。

暫無
暫無

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

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