来自未提交的高管的结果,例如RETURNING?

时间:2014-04-14 19:28:15

标签: c++ postgresql prepared-statement libpqxx

使用libpqxx,是否有可能使用exec但尚未commit的一个预准备语句将结果存储在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中的write_parent_table以查看if( == "")。如果不是,它就会继续;否则,我会commit在那里让它失败,或者更好的是在可能的情况下取消交易;但是,如果可能的话,我还不知道如何做到这一点。

INSERT child_table parent_table INSERT总会有{{1}}的不确定数量。

1 个答案:

答案 0 :(得分:1)

使用data-modifying 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;
    }
}

Search for [postgres] & "data-modifying CTE"了解更多示例。
也叫做#34;可写的CTE&#34; (或&#34;可写的CTE&#34;)。

多个孩子

对于单个父级和 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或空数组{}