【问题标题】:Prepared statement with an array field PostgreSQL&PHP带有数组字段 PostgreSQL 和 PHP 的准备好的语句
【发布时间】:2014-10-19 18:25:41
【问题描述】:

有下表:

CREATE TABLE submission (
    num SERIAL,
    user_id INTEGER NOT NULL,
    assignment_id INTEGER NOT NULL,
    timestamp TIMESTAMP,
    lti_info TEXT[][],
    PRIMARY KEY(num),
    FOREIGN KEY (user_id) REFERENCES canvas_user,
    FOREIGN KEY (assignment_id) REFERENCES assignment
);

我想用 php 函数在桌子上进行 INSERT,类似于以下(不工作)代码:

function create_submission($user_id, $assignment_id, $lti_info) {
        # INSERT everything except lti info
        $query = "INSERT INTO submission (user_id, assignment_id, timestamp) VALUES ($1, $2, LOCALTIMESTAMP) RETURNING num";
        pg_prepare($this->con, "createsub", $query);
        $rs = pg_execute($this->con, "createsub", array($user_id, $assignment_id));
        $row = pg_fetch_row($rs);
        $sub_num = $row[0];

        # update table to insert lti_info
        $serialized = serialize($lti_info);
        $query = "UPDATE submission SET lti_info = $1";
        pg_prepare($this->con, "insertlti", $query);
        pg_execute($this->con, "insertlti", array($serialized));
        return $sub_num;
    }

我曾尝试对类似问题进行序列化并执行类似此答案的操作:Supply a prepared statement with an array,但没有成功。

如果你们中的任何人能提供 create_submission 函数的解决方案,我将非常高兴。

更新:

当我执行 create_submission 时,它会在更新点出现以下错误:

pg_execute():查询失败:错误:数组值必须以“{”或 维度信息

lti_info 是字符串的关联数组,类似于:

lti_info = array (
"oauth_consumer_key" => "example",
"oauth_consumer_secret" => "secret"
)

注意:我不介意一切都是在一次插入中完成的,还是先插入“正常”字段然后再插入 lti_info 数组。

【问题讨论】:

  • 那么问题出在哪里?当你运行它时会发生什么?相反应该发生什么?什么是lti_info,为什么插入后必须更新?
  • 我已经更新了问题,试图回答你的问题。

标签: php arrays postgresql multidimensional-array parameter-passing


【解决方案1】:

Postgresql 中没有关联数组。要将其保存为二维数组,有必要构建一个合适的字符串以传递给 Postgresql 并在返回时执行相反的操作。保存为 JSON 更简单:

create table submission (
    num serial,
    user_id integer not null,
    assignment_id integer not null,
    timestamp timestamp,
    lti_info json,
    primary key(num)
);

使用json_encode

<?php
$lti_info  = array (
    "oauth_consumer_key" => "example",
    "oauth_consumer_secret" => "secret"
);

$query = "
    insert into submission (user_id, assignment_id, timestamp, lti_info) values
    ($1, $2, localtimestamp, $3)
    returning num
";

$conn = pg_connect ( "port=5432 user=cpn dbname=cpn");
pg_prepare($conn, "createsub", $query);
pg_execute($conn, "createsub", array(1, 1, json_encode($lti_info)));

$query = "select * from submission";
pg_prepare($conn, "select", $query);
$rs = pg_execute($conn, "select", array());

$lti_info = (array) json_decode(pg_fetch_result($rs, "lti_info"));

print_r ($lti_info);
?>

输出

    Array
(
    [oauth_consumer_key] => example
    [oauth_consumer_secret] => secret
)

【讨论】:

  • 如果不是我当前版本的 PostgreSQL (8.4) 和 9.2 中引入的 JSON 数据类型列,答案会很好。我无法升级 PostgreSQL...任何解决方案?
  • @otorrillas 如果数据只在 PHP 端使用,则将其保存为 lti_info text,,PHP 代码将相同。如果它将在 Postgresql 端使用,则另存为两个单独的列。为什么要将密钥和秘密组合在一个列中?为什么不是两个?
  • 它只会在PHP端使用,在这种情况下与db的交互只是为了存储。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-13
  • 2015-08-08
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多