2009-09-24 6 views
0

J'ai écrit un package pour interroger des lignes à partir d'une table. Cette requête select appelle d'autres fonctions et renvoie toutes les lignes de la table. Mais quand j'écris un paquet avec toutes les fonctions et les sprocs, mon sproc avec une instruction select me donne une erreur disant que je ne peux pas exécuter sans instruction. Mais si je l'utilise, il ne retournera qu'une seule ligne. Comment puis-je récupérer toutes les lignes en utilisant Oracle Sp?Interrogation de plusieurs lignes à partir d'une table Oracle à l'aide du package

Procedure GetData As 
BEGIN 
Select Jobid, JobName, JobLocation, JobCompany, X(jobid) FROM jobsTable; END GetData; 
END; 

je devais changer à la suite faire l'erreur disparaissent:

Procedure GetData As 
    r_Jobid jobsTable.jobid%type; 
    r_JobName jobsTable.jobName%type; 
    r_JobLocation jobsTable.jobLocation%type; 
    r_temp varhar2(10); 
BEGIN 

    Select Jobid, JobName, JobLocation, JobCompany, X(jobid) 
    INTO r_jobid, r_jobName, r_jobLocation, r_temp 
    FROM jobsTable; 

END GetData; 

END; 
+0

Pourriez-vous ajouter dans l'erreur exacte que vous obtenez? – SeanJA

+0

votre code proc stocké serait également utile. – akf

+0

comment ajouter un extrait de code –

Répondre

5

Ceci est une meilleure approche de revenir plusieurs lignes d'une fonction:

FUNCTION GET_DATA() 
RETURN SYS_REFCURSOR IS 

results_cursor SYS_REFCURSOR; 

BEGIN 

    OPEN results_cursor FOR 
    SELECT t.jobid, 
      t.jobName, 
      t.joblocation, 
      t.jobcompany, 
      X(t.jobid) 
     FROM JOBSTABLE t; 

    RETURN results_cursor; 

END; 

Je suis d'accord avec AFK bien que cela ne semble pas être ce que vous devez vraiment utiliser. Voici ma recommandation pour l'utilisation d'un curseur:

CURSOR jobs IS 
    SELECT t.jobid, 
      t.jobName, 
      t.joblocation, 
      t.jobcompany, 
      X(t.jobid) 
     FROM JOBSTABLE t; 

    v_row jobs%ROWTYPE; --has to be declared AFTER the cursor to be able to reference the row type 

BEGIN 

    OPEN jobs; 
    FETCH jobs INTO v_row; 

    IF jobs%FOUND THEN 
    --do stuff here, per row basis 
    --access columns in the row using: v_row.jobid/etc 
    END IF; 

    CLOSE jobs; 

END; 

Savez-vous que ceci:

Procedure GetData As 
    r_Jobid jobsTable.jobid%type; 
    r_JobName jobsTable.jobName%type; 
    r_JobLocation jobsTable.jobLocation%type; 
    r_temp varhar2(10); 

... signifie que vous avez défini des variables locales? Vous ne serez pas en mesure d'obtenir des informations sur la procédure. Si vous le faites, vous auriez besoin de paramètres, comme ceci:

Procedure GetData(IO_R_JOBID IN OUT JOBSTABLE.JOBID%TYPE, 
        IO_R_JOBNAME IN OUT JOBSTABLE.JOBNAME%TYPE, 
        IO_R_JOBLOCATION IN OUT JOBSTABLE.JOBLOCATION%TYPE, 
        IO_R_TEMP IN OUT VARCHAR2(10)) AS 

J'utilise le IO_ de noter que les paramètres sont IN/OUT. J'utiliserais IN_ ou OUT_ le cas échéant. Mais la clé ici est de définir OUT si vous voulez récupérer un paramètre.

Aussi - les paquets sont juste le groupement logique des procédures & fonctions, avec la possibilité de définir des constantes étendues au paquet. Le package lui-même n'exécute aucun code SQL - il s'agit toujours d'une fonction ou d'une procédure en cours d'exécution. Dieu comme je souhaite que SQL Server ait des paquets ...

+0

Savez-vous que ce ne sont pas des paramètres mais des variables locales dont vous parlez? IN/OUT ne s'applique pas. Soit cela ou l'affiche originale est fausse. – jva

+0

@jva: Thx, corrigé. Mauvaise compréhension de la lecture causée par le manque de sommeil. –

+0

Je dois faire une comparaison et effectuer une logique métier sur certaines colonnes de ma table et renvoyer ces données à mon programme C#. J'ai donc utilisé le paquet pour écrire des fonctions pour chaque BL et les appeler directement dans une requête select et essayait de renvoyer ce résultat et de le charger dans datatable. Il y avait 1 million d'enregistrements et mon SP fonctionne pour toujours ... je devais le tuer .. –

0

Vous devez utiliser un curseur pour plusieurs résultats de retour. Jetez un oeil à this article on using Cursors pour quelques détails.

Vous pouvez faire quelque chose comme:

DECLARE 
    CURSOR myCur IS 
     SELECT Jobid, JobName, JobLocation, JobCompany, X(jobid) 
     FROM jobsTable; 
BEGIN 
    FOR resultRow in myCur 
    LOOP 
    --do your stuff here 
    END LOOP; 
END; 
1

Vous pouvez utiliser une fonction pipelined. Pour cet exemple, je ne récupère que les colonnes d'ID, mais il suffit d'ajouter les autres.

CREATE PACKAGE jobsPkg AS 
    TYPE jobsDataRec IS RECORD (jobid jobsTable.jobid%type); 
    TYPE jobsDataTab IS TABLE OF jobsDataRec; 
    FUNCTION getJobsData RETURN jobsDataTab PIPELINED; 
END jobsPkg; 
/

CREATE PACKAGE BODY jobsPkg AS 
    FUNCTION getJobsData RETURN jobsDataTab PIPELINED 
    IS 
    output_record jobsDataRec; 
    BEGIN 
    FOR input_record IN (SELECT jobid FROM jobsTable) LOOP 
     output_record.jobid := input_record.jobid; 
     PIPE ROW (output_record); 
    END LOOP; 
    END getJobsData; 
END jobsPkg; 
/

Cette fonction peut alors être utilisée comme source de ligne:

SELECT * FROM TABLE(jobsPkg.getJobsData); 
Questions connexes