1

使用 libpqxx,是否可以将一个已准备好exec但尚未经过测试的准备好的语句commit存储在 a 中result以供以后准备好的语句中使用?

如果是这样,如何做到这一点?

代码

为了便于阅读,我已将其剥离,但这基本上是我想要做的:

void prepare_write_parent_table(connection_base &c){
    try
    {
        c.prepare("write_parent_table", 
            "INSERT INTO parent_table (column_1) "
            "SELECT $1 "
            "RETURNING id"
        )
        ("character", pqxx::prepare::treat_string);
    }
    catch (const exception &e)
    {
        cerr << e.what() << endl;
    }
}

string write_parent_table(transaction_base &t, string data){
    try
    {
        result parent_table_result = t.prepared("write_parent_table")(data).exec();
        return parent_table_result[0][0].c_str();

    }
    catch (const exception &e)
    {
        cerr << e.what() << endl;
        return "";
    }
}

void prepare_write_child_table(connection_base &c){
    try
    {
        c.prepare("write_child_table", 
            "INSERT INTO child_table (parent_table_id, column_a) "
            "SELECT $1, $2 "
        )
        ("character", pqxx::prepare::treat_string)
        ("character", pqxx::prepare::treat_string);
    }
    catch (const exception &e)
    {
        cerr << e.what() << endl;
    }
}

return检查from以write_parent_table查看if( == ""). 如果不是,则继续;否则,我会commit让它失败,或者如果可能的话,最好取消交易;但是,如果可能的话,我还不知道该怎么做。

per中总会有不确定的INSERTs数量。child_tableparent_table INSERT

4

1 回答 1

1

通过使用数据修改 CTE对两个插入使用单个 SQL 语句来简化操作。这比在客户端中存储中间状态要快得多。

INSERT子表中的 仅当父表中的第一个成功INSERT并返回时才会发生id

void prepare_write_both_tables(connection_base &c){
    try
    {
       c.prepare("write_both_tables", 
          "WITH p AS ("
             "INSERT INTO parent_table (column_1) "
             "SELECT $1 "
             "RETURNING id) "
          "INSERT INTO child_table (parent_table_id, column_a) "
          "SELECT p.id, $2 "
          "FROM   p"
        )
        ("character", pqxx::prepare::treat_string)
        ("character", pqxx::prepare::treat_string);
    }
    catch (const exception &e)
    {
        cerr << e.what() << endl;
    }
}

搜索 [postgres] 和“数据修改 CTE”以获取更多示例。
也称为“可写 CTE”(或“可写 CTE”)。

多个孩子

对于单亲0 到多个孩子:

void prepare_write_both_tables(connection_base &c){
    try
    {
       c.prepare("write_both_tables", 
          "WITH p AS ("
             "INSERT INTO parent_table (column_1) "
             "SELECT $1 "
             "RETURNING id) "
          "INSERT INTO child_table (parent_table_id, column_a) "
          "SELECT p.id, a "
          "FROM   p, unnest($2::text[]) AS a"
        )
        ("character", pqxx::prepare::treat_string)
        ("character", pqxx::prepare::treat_string);
    }
    catch (const exception &e)
    {
        cerr << e.what() << endl;
    }
}

其中第二个参数是array of text文本表示。例子:

{foo,bar,baz}

这将插入与文本数组中的元素一样多的行。对于 0 个孩子通过NULL或一个空数组{}

于 2014-04-14T23:51:53.887 回答