结果,例如返回,从uncomitted高管?(Results, such as RETURNING,

2019-10-19 21:28发布

随着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;
    }
}

returnwrite_parent_table进行检查,看if( == "") 如果不是,则进入; 否则,我会commit有让它失败或更优选如果可能的话取消交易; 不过,我还不知道该怎么做,如果它甚至有可能。

总是会有一个不确定的量的INSERT s转换child_tableparent_table INSERT

Answer 1:

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

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或空数组{}



文章来源: Results, such as RETURNING, from uncomitted execs?