2009-05-07 5 views
1

Voici mon script:Pourquoi DBI de Perl se plaint-il de "Fetch tenté sur un curseur non ouvert"?

$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"); 

Note: $dbstr est un nom de base de données valide.

Je ne suis pas un programmeur de base de données. Qu'est-ce que je fais mal qui est à l'origine du script Perl fail dire:

DBD::Informix::db selectrow_array failed: SQL: -400: Fetch attempted on unopen cursor.

Si j'écris un script simple pour se connecter à la base de données $dbstr et afficher le contenu de la table, il fonctionne très bien, mais le code ci-dessus ne fonctionne pas.

+0

S'il vous plaît noter qu'il ya des endroits documentés pour obtenir un soutien DBD :: Informix (ce n'est pas un d'entre eux, mais il n'existait pas quand la dernière version de DBD :: Informix était créé). S'il vous plaît noter, encore plus important, qu'il existe un * LOT * d'informations de version qui est nécessaire pour répondre à des questions plus complexes, y compris la version de: Perl, DBI, DBD :: Informix, ESQL/C (ou CSDK), IDS (ou autre SGBD Informix), plate-forme, et parfois même le compilateur. Ces exigences sont énoncées dans la documentation avec la source. Il y a même un script fourni pour en recueillir la plus grande partie - InformixTechSupport. –

Répondre

1

Veuillez lire la documentation pour DBD::Informix, en particulier la section "CONNECTING_TO_A_DATABASE". Le code minimum requis pour se connecter à une base de données Informix semble être:

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

Ainsi, vous devrez fournir plus que le nom de la base de données.

+0

La question disait que la connexion fonctionnait - et donc ils fournissaient plus que le nom de la base de données. La x-ref à la documentation DBD :: Informix est toujours utile, cependant. –

3

La méthode selectrow_array est destinée à être utilisée avec des instructions renvoyant des ensembles de résultats. L'instruction SET ISOLATION n'est pas une telle instruction - elle échouera.

Si l'erreur -400 est la meilleure erreur possible est légèrement discutable - parfois je vais jeter un coup d'oeil et voir si quelque chose peut être fait. Toutefois, IIRC, la méthode selectrow_array est fournie par DBI plutôt que DBD :: Informix, DBI le construit donc à partir de primitives de niveau inférieur. Par conséquent, ces primitives ne peuvent pas fournir la validation que la fonction de niveau supérieur pourrait fournir, car elles doivent également fonctionner séparément.

La bonne façon d'écrire ce code est:

$db_handle->do("set isolation mode to dirty read"); 
3

Il n'y a aucun résultat pour que vous rapportez de la déclaration que vous exécutez:

set isolation to dirty read 

si selectrow_array() est la mauvaise méthode pour appeler . Utilisez $dbh->do(...) à la place:

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

Voici une explication plus longue de l'erreur -400:

-400 Fetch attempted on unopen cursor.

This FETCH statement names a cursor that has never been opened or has been closed. Review the program logic, and check that it will open the cursor before this point and not accidentally close it. Unless a cursor is declared WITH HOLD, it is automatically closed by a COMMIT WORK or ROLLBACK WORK statement.

Comme le souligne de Jonathan, cela ne peut être l'erreur la plus claire, mais il ne fait un certain sens une fois que vous comprenez Que se passe-t-il.

1

set isolation to dirty read n'est pas une requête, c'est une instruction. Seules les requêtes vont dans selectrow_array. Vous avez besoin 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; 
Questions connexes