Почему DBI Perl жалуется на «Fetch предпринял попытку открыть курсор»? - PullRequest
1 голос
/ 07 мая 2009

Вот мой сценарий:

$db_handle=DBI->connect("$dbstr", "", "",
{RaiseError => 0, AutoCommit => 0, PrintError => 1}) 
|| die "Connect error: $DBI::errstr" ;
$result=$db_handle->selectrow_array("set isolation to dirty read");

Примечание: $dbstr является допустимым именем базы данных.

Я не программист базы данных. Что я делаю неправильно, из-за чего скрипт Perl не может сказать:

DBD :: Informix :: db selectrow_array завершилась неудачно: SQL: -400: попытка получения не открываемого курсора.

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

Ответы [ 4 ]

3 голосов
/ 07 мая 2009

Метод selectrow_array предназначен для использования с операторами, возвращающими наборы результатов. Оператор SET ISOLATION не является таким оператором - он потерпит неудачу.

Вопрос о том, является ли ошибка -400 наилучшей из возможных, является спорным вопросом - когда-нибудь я посмотрю и посмотрю, можно ли что-нибудь сделать. Однако в IIRC метод selectrow_array предоставляется DBI, а не DBD :: Informix, поэтому DBI строит его из примитивов более низкого уровня. Следовательно, эти примитивы не могут обеспечить проверку, которую могла бы обеспечить функция более высокого уровня, потому что они также должны работать отдельно.

Правильный способ написать этот код:

$db_handle->do("set isolation mode to dirty read");
3 голосов
/ 07 мая 2009

Нет результатов для извлечения из выполняемого вами оператора:

set isolation to dirty read

поэтому selectrow_array() - неправильный метод для вызова. Используйте $ dbh-> do (...) вместо:

$db_handle->do('set isolation to dirty read');

Вот более подробное объяснение ошибки -400:

-400 Произведена попытка извлечения неоткрытого курсора.

Этот оператор FETCH называет курсор, который никогда не был открыт или имеет был закрыт. Проверьте логику программы и убедитесь, что она откроет наведите курсор на эту точку и не случайно ее закройте. Если только курсор объявляется WITH HOLD, автоматически закрывается командой COMMIT WORK или ROLLBACK WORK заявление.

Как указывает Джонатан, это может быть не самой очевидной ошибкой, но в ней есть смысл, когда вы понимаете, что происходит.

1 голос
/ 07 мая 2009

set isolation to dirty read это не запрос, это утверждение. Только запросы идут в selectrow_array. Вам нужно do:

#!usr/bin/perl

use strict;
use warnings;

use DBI;

my $dbi = "dbi:Informix:dbname";

my $dbh = DBI->connect(
    $dbi,
    "",
    "",
    {
        RaiseError => 1,
        AutoCommit => 0,
        PrintError => 1,
        ChopBlanks => 1,
    }
) or die "Connect error: $DBI::errstr";

my $result = $dbh->do("set isolation to dirty read");

$dbh->disconnect;
1 голос
/ 07 мая 2009

Пожалуйста, прочитайте документацию для DBD :: Informix , особенно в разделе "CONNECTING_TO_A_DATABASE". Минимальный необходимый код для подключения к базе данных Informix:

$dbh = DBI->connect("dbi:Informix:$database");

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

...