2012-07-23 2 views
1

J'ai reçu un accès en lecture à une base de données Oracle pour obtenir des données pour ma propre base de données. Le DBA m'a donné une procédure stockée qu'il m'assure que c'est tout ce dont j'ai besoin, mais je n'ai pas encore pu l'exécuter depuis Ruby.Comment exécuter une procédure stockée Oracle dans Ruby

J'ai la gemme ruby-oci8 et le client instantané Oracle.

Voici ce que j'ai géré jusqu'à maintenant.

require 'oci8' 
conn = OCI8.new('user','pass','//remoteora1:1521/xxxx') 
=> #<OCI8::RWHRUBY> 
cursor = conn.parse("call REPOSITORY.GET_PMI_ADT('722833', 'W', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)") 
=> #<OCI8::Cursor:0x56f4d50> 

Et c'est là que je suis bloqué. J'ai cet objet OCI8 :: Cursor mais je ne sais pas quoi en faire. Cela devrait me renvoyer tout un tas de résultats (où les valeurs nulles sont dans la requête) mais je n'ai rien. Exécuter cursor.exec avec et sans paramètres (je ne suis pas sûr que les paramètres dont j'ai besoin si) me donne des erreurs.

cursor.exec donne

OCIError: ORA-06553: PLS-: 
ORA-06553: PLS-: 
ORA-06553: PLS-: 
ORA-06553: PLS-306: wrong number or typ 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 
ORA-06553: PLS-306: wrong number or type of arguments in call to 'GET_PMI_ADT' 

etc ...

cursor.fetch donne

OCIError: ORA-24338: statement handle not executed 

Est-ce que quelqu'un a des idées ici? Je suis bien au dessus de ma tête.

Une mise à jour ici pour tous ceux qui regardent encore. Si je change la procédure stockée à

BEGIN REPOSITORY.GET_PMI_ADT('722833', 'W', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); END; 

Je reçois maintenant l'erreur;

OCIERROR: ORA-06550: line 1, column 45: 
PLS-00363: expression ' NULL' cannot be used as an assignment target 

Est-ce que cela confirme que la procédure stockée est incorrecte? Y at-il quelque chose d'évident à faire pour le corriger?

+0

Désolé, J'aurais dû inclure cela. Ajouté ci-dessus. – brad

+0

Avez-vous essayé d'exécuter cette ligne de code exacte dans Oracle? Il semble qu'il y ait un problème avec la procédure stockée que vous essayez d'invoquer. – Strelok

+0

Je n'ai pas accès à la base de données Oracle et le DBA m'a assuré qu'il n'y aurait pas de problème avec sa procédure stockée ... J'ai cependant mes soupçons. – brad

Répondre

3

Cela devrait aider:

http://rubyforge.org/forum/forum.php?thread_id=11295&forum_id=1078

échantillon est comme ci-dessous:

msi est IN statut et remaining_credit variables sont les variables OUT

cursor = conn.parse ('begin ROAMFLEX.GETMSISDNSTATUS(:msi, :status, :remaining_credit); end;') 
cursor.bind_param(':msi', '250979923') 
cursor.bind_param(':status', nil, String, 20) 
cursor.bind_param(':remaining_credit', nil, String, 50) 
cursor.exec() 
puts cursor[':status'] 
puts cursor[':remaining_credit_amount'] 
+0

Merci beaucoup! Cet exemple était exactement ce dont j'avais besoin pour modifier mon code pour le faire fonctionner. Après avoir abandonné cela pendant un an, je suis maintenant capable de le faire fonctionner. – brad

1

L'erreur que vous recevez

PLS-00363: expression ' NULL' cannot be used as an assignment target 

signifie que dans la procédure stockée, certains paramètres sont définis comme IN OUT ce qui signifie qu'ils doivent être des variables. Il est assez fréquent d'utiliser un paramètre pour contenir une valeur de retour indiquant si une procédure a réussi ou échoué bien qu'il soit plus courant d'utiliser une fonction où vous pouvez retourner un booléen vrai/faux pour indiquer le succès.

Vous devez donner au DBA le message d'erreur que vous obtenez et demander une signature complète pour la procédure que vous appelez qui devrait vous indiquer quelles variables vous passez sont IN/OUT. Tout ce qui est IN seulement peut être passé une constante ou NULL alors que ceux qui sont OUT ou IN OUT doivent être des variables et vous devrez peut-être faire quelque chose en fonction de ce que vous obtenez dans ces variables.

1
# PL/SQL records or object type parameters should be passed as Hash 
# test_full_name is procedure name in oracle 
# p_employee holds parameter list 
#employee_id is first param defined in stored procedure 

require 'ruby-plsql' 

p_employee = { :employee_id => 1, :first_name => 'First', :last_name => 'Last', :hire_date => Time.local(2000,01,31) } 
plsql.test_full_name(p_employee) #plsql should hold connection object 
Questions connexes