c++ - 行号 0 超出范围 0..-1 LIBPQ

标签 c++ postgresql std libpq libpqxx

query = "select * results where id = '";
query.append(ID);
query.append("'");
res = PQexec(conn, query.c_str());

执行此语句后,出现以下错误。

row number 0 is out of range 0..-1
terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_S_construct null not valid

但是,当我在 postgresql 中运行相同的查询时,它没有任何问题。

select * from results where id = 'hello'

唯一的问题是,如果传递的查询参数不在数据库中,则会抛出运行时错误。如果您提供数据库中的确切查询参数,它会正常执行。

最佳答案

这是两个不同的错误,而不是一个。这个错误:

row number 0 is out of range 0..-1

来自 libpq,但由您未在此处显示的代码报告。

错误:

terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_S_construct null not valid

不是来自 PostgreSQL,而是来自您的 C++ 运行时。

我无法确切地说出它来自哪里。你真的应该在调试器下运行程序来说明这一点。但是,如果我不得不根据显示的代码进行猜测,我会说 ID 为空,因此:

query.append(ID);

因此中止程序。


另外,您的代码表现出一种非常不安全的做法,您通过字符串连接来编写 SQL。这使得 SQL injection exploits很简单。

想象一下,如果您的“ID”变量被恶意用户设置为 ';DROP TABLE results;-- 会发生什么。

不要通过附加字符串将用户提供的值插入到 SQL 中。

相反,通过 PQexecParams 使用绑定(bind)参数。它看起来很复杂,但大多数参数对于简单使用来说都是可选的。假设 ID 是非 null std::string,您的查询版本将如下所示:

PGresult res;
const char * values[1];

values[0] = ID.c_str();

res = PQexecParams("SELECT * FROM results WHERE id = $1",
                   1, NULL, values, NULL, NULL, 0);

如果您需要处理空值,则需要另一个参数;见the documentation .

关于c++ - 行号 0 超出范围 0..-1 LIBPQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29540467/

相关文章:

c++ - (错误 C2678)错误 : No operator "<<" matches these operands

c++ - 检测谁启动了 COM 服务器

c++ - 删除指针的部分内存

ruby-on-rails - 推送到 Heroku 被拒绝

postgresql 查询未返回预期结果

postgresql - Osm2pgsql 由于错误 : PBF error: invalid BlobHeader size (> max_blob_header_size) 而失败

c++ - 在 C++11 中从 std::deque move 一个元素

c++ - 为什么没有 std::stou?

c++ - 为什么在C++中的类中定义方法时不存在多重定义错误?

c++ - 了解字符数组初始化和数据存储