问题描述
void DB_Series_Base::doInsert(pqxx::connection &conn,Series &obj) {
pqxx::work work {conn};
string sql { string{"INSERT INTO series ("} + INSERT_LIST + ") VALUES ($1,$2) RETURNING id" };
pqxx::result results = work.exec_params(sql,obj.getName().length() > 0 ? obj.getName().c_str() : nullptr,obj.getUniverseId() != 0 ? obj.getUniverseId(): nullptr);
work.commit();
obj.setId(results[0][0].as<int>());
}
这不会编译出现错误“非指针操作数类型‘int’与 nullptr 不兼容”。好的,我明白了。三元运算符需要返回数据类型一致的值。
在这里,UniverseId 是 Universe 表的外键。
我试过了:
void DB_Series_Base::doInsert(pqxx::connection &conn,Series &obj) {
int universeId = obj.getUniverseId();
pqxx::work work {conn};
string sql { string{"INSERT INTO series ("} + INSERT_LIST + ") VALUES ($1,&universeId);
work.commit();
obj.setId(results[0][0].as<int>());
}
Undefined symbols for architecture x86_64:
"pqxx::string_traits<int*>::size_buffer(int* const&)",referenced from:
unsigned long pqxx::size_buffer<int*>(int* const&) in libauthor-mac.a(DB_Series_Base.o)
"pqxx::string_traits<int*>::into_buf(char*,char*,int* const&)",referenced from:
std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char> > pqxx::to_string<int*>(int* const&) in libauthor-mac.a(DB_Series_Base.o)
"pqxx::nullness<int*,void>::is_null(int* const&)",referenced from:
bool pqxx::is_null<int*>(int* const&) in libauthor-mac.a(DB_Series_Base.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command Failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:39: AuthorServer] Error 1```
The only other thing I can think of is to entirely build custom sql for each insert / update,and embed "NULL" in the VALUES section instead of $2 etc. That's kind of gross,but I can do it if no one has a better suggestion.
So... how can I pass either the actual foreign key (universeId) -or- nullptr as apprpriate?
解决方法
哦,这很酷。我发现了 nullif
函数。
void
TestDatabase::testNullForeignKeys() {
connect();
string sqlSeries { "INSERT INTO series(name,universe_id) VALUES ($1,nullif($2,0)) RETURNING id" };
int universeId = 0;
pqxx::work populateSeries {*connection};
pqxx::result results = populateSeries.exec_params(sqlSeries,"Test Series",universeId);
populateSeries.commit();
}
注意 INSERT 语句的 VALUES 部分中的 nullif($2,0)
。这说明了什么:
如果第一个参数 == 第二个,则返回 null。否则返回第一个参数。因此,如果 UniverseId 为 0,则 nullif 返回 NULL。否则返回真实值。
这解决了我的问题。