使用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}}的不确定数量。
答案 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
或空数组{}
。