对于 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;
}
}
write_parent_table
的return
被检查以查看if( == "")
。如果不是,则继续;否则,我将在那里提交
让它失败,或者如果可能的话最好取消交易;但是,如果可能的话,我还不知道该怎么做。
每个 parent_table
INSERT
总是会有不确定数量的 INSERT
到 child_table
中。
最佳答案
使用 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"更多示例。
也称为“可写 CTE”(或“可写 CTE”)。
多个 child
对于一个单亲 parent 和0到多个 child :
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;
}
}
其中第二个参数是文本表示形式的文本数组
。示例:
{foo,bar,baz}
这会插入与文本数组中的元素一样多的行。对于 0 个 child ,传递 NULL
或一个空数组 {}
。
关于c++ - 结果,例如 RETURNING,来自未提交的 execs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23068613/