2017-02-03 1 views
1

Je rencontre des erreurs lors de l'exécution d'une procédure stockée via Perl.perl: exécution d'une procédure stockée qui utilise select

Les énoncés suivants fonctionnent très bien dans sqldeveloper et renvoient des résultats attendus

EXEC alpha.beta.do_something() 

Cela ne génère pas de sortie, comme prévu

Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName 

Cela génère une sortie qui nous est donnée à des gars DBA . Il a ce format en termes de DB: Output Type:Ref Cursor. Le curseur a deux colonnes, a et b

Lors de l'exécution de Perl, j'obtiens des erreurs lors de l'exécution de la deuxième instruction.

Voici le code Perl que j'utilise:

sub execute_procedure { 
    my $dbh  = shift; 
    my $procedure = shift; 

    my $statement = "BEGIN $procedure; END;" 
    my $sth; 
    eval {$sth = $dbh->prepare($statement);}; 
    eval {$sth->execute();}; 

    if ([email protected]) { 
     print "failed"; 
    } else { 
     print "passed"; 
    } 
} 

# Call 1 
execute_procedure($dbh, "alpha.beta.do_something()") 

# Call 2 
execute_procedure($dbh, "Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName") 

Appel 1 fonctionne comme prévu, ne génère pas d'erreurs

appel 2 résultats dans cette erreur

"Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName" results in :PLS-00428: an INTO clause is expected in this SELECT statement (DBD ERROR: error possibly near <> indicator at char 6 in 'BEGIN <>Select alpha.beta.get_result(alpha.STRING_ARRAY('xyz')) from tableName; END;')

si Je supprime BEGIN et END de la déclaration dans la fonction execute_procedure comme ceci:

# my $statement = "BEGIN $procedure; END;"; 
my $statement = "$procedure"; 

alors il ne génère pas d'erreur, mais il renvoie un résultat que je ne sais pas comment analyser

my $result = $sth->fetchrow_hashref; 
print Dumper($result) 

résultats dans:

$VAR1 = { 
    'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless({}, 'DBI::st') 
}; 

donc, mes questions sont

  1. Quelle est la bonne façon d'exécuter une procédure stockée qui utilise l'instruction SELECT? Doit-il être appelé avec BEGIN $procedure; END; ou sans le BEGIN/END?

  2. Comment puis-je obtenir les données réelles de bless({}, 'DBI::st')? Je l'ai essayé d'utiliser différentes options ira chercher fetchrow, fetchrow_hashref etc., mais je ne suis pas en mesure d'obtenir les données réelles de l'objet

+0

Cela semble très familier. Avez-vous déjà demandé la même chose ces derniers jours? – simbabque

+1

oui, je l'ai demandé hier, mais il manquait des détails et les gens m'ont demandé de fournir le code. Je viens de mettre à jour l'autre question et je l'enlèverai bientôt. – comatose

+1

Eh bien maintenant c'est super clair. Vois ma réponse. – simbabque

Répondre

1
$VAR1 = { 'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless({}, 'DBI::st') }; 

La valeur ici est a DBI statement handle. C'est la même chose que vous obtenez lorsque vous faites my $sth = $dbh->prepare(...). Il a probablement déjà été exécuté, vous pouvez donc appeler n'importe laquelle des méthodes de récupération.

my $result = $sth->fetchrow_hashref; 
while (
    my $res = $result->{'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))'} 
     ->fetchrow_hashref 
) { 
    # ... 
} 

Mais cela semble horrible, et vous pourriez ne pas savoir ce que les clés sont. Donc, vous pourriez vouloir juste itérer sur chacun d'eux.

my $result = $sth->fetchrow_hashref; 
foreach my $key (keys %${ $result }) { 
    print "Processing results of $key\n"; 
    while (my $res = $result->{$key}->fetchrow_hashref) { 
     # do things with the $res 

    } 
} 

Vous avez juste besoin de trouver une bonne façon de gérer les résultats.La boucle ci-dessus fonctionne également s'il n'y a qu'une seule clé dans le hash ref, donc vous pouvez simplement l'utiliser de toute façon et espérer qu'il y en aura toujours une seule.

+0

Cela fonctionne, merci! donc juste pour clarifier la question (1), pour les procédures stockées qui retournent quelque chose, les exécuter comme "BEGIN $ procedure; END;"; ce n'est pas une bonne idée? – comatose

+0

@comatose Je ne sais pas. Je n'ai pas utilisé cette syntaxe auparavant. – simbabque