微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

pqxx 和空外键

如何解决pqxx 和空外键

我有以下代码

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。否则返回真实值。

这解决了我的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。