Номер строки 0 находится вне диапазона 0..-1 LIBPQ

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'

Единственная проблема заключается в том, что если переданный параметр запроса отсутствует в базе данных, он выдаст ошибку времени выполнения. Если вы предоставите точный параметр запроса, который находится в базе данных, он выполняется нормально.

2 ответа

Это две отдельные ошибки, а не одна. Эта ошибка:

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-инъекций.

Представьте, что произошло бы, если бы ваша переменная "ID" была установлена ​​в ';DROP TABLE results;-- злоумышленником.

Не вставляйте пользовательские значения в SQL, добавляя строки.

Вместо этого используйте параметры связывания через PQexecParams, Это выглядит сложно, но большинство параметров не являются обязательными для простого использования. Версия для вашего запроса, при условии, что ID ненулевой 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);

Если вам нужно обработать пустые значения, вам нужен другой параметр; см. документацию

Может быть, слишком поздно, но просто хочу поставить мои 5 центов.

Получил эту ошибку также в эти дни с очень простой хранимой процедурой типа:

CREATE OR REPLACE FUNCTION selectMsgCounter()
RETURNS text AS
$BODY$
DECLARE
           msgCnt text;
BEGIN
msgCnt:= (SELECT max(messageID)::text from messages);
RETURN 'messageCounter: ' || msgCnt;
END
$BODY$
LANGUAGE plpgsql STABLE;

Сделал некоторую отладку с:

if (PQntuples(res)>=1)
 {
 char* char_result=(char*) realloc(NULL,PQgetlength(res, 0,0)*sizeof(char));
 strcpy( char_result,PQgetvalue(res, 0, 0));

 bool ok=true;
 messageCounter=QString(char_result).remove("messageCounter: ").toULongLong(&ok);
 if (!ok) messageCounter=-1;
 qDebug()<<"messageCounter: " << messageCounter;
 free(char_result);
 PQclear(res);
 PQfinish(myConn); // or do call destructor later?
 myConn=NULL;
 }
 else
 {
     fprintf(stderr, "storedProcGetMsgCounter Connection Error: %s",
             PQerrorMessage(myConn));
     PQclear(res);
     PQfinish(myConn); // or do call destructor later?
     myConn=NULL;
 }

Оказалось, что владельцем хранимой процедуры был не тот, чьи учетные данные я использовал для входа в систему. Так что, по крайней мере, в моем случае эта ошибка "номер строки 0 выходит за пределы диапазона 0..-1" на первый взгляд оказалась ложноположительной.

Другие вопросы по тегам