2015-02-25 3 views
0

im essayant de faire quelque chose comme ceci:paramètres dynamiques non types SQL Oracle

create function getData(r1 IN TABLE1%ROWTYPE,col1 string, valor OUT string)RETURN string AS 

    instruccion VARCHAR2(500); 
    valor VARCHAR(200); 
BEGIN 

    valor := r1.col1; 

    return valor; 

END getData; 

Une procédure qui prend comme paramètres un enregistrement et le nom de la colonne et de redonner la valeur et:

CREATE procedure p1 as 

    vData VARCHAR2(80); 
    v1 VARCHAR2(80); 
    vValue VARCHAR2(80); 

    inst VARCHAR2(500); 

    CURSOR vTable2 IS SELECT * FROM TABLE2; 

    CURSOR vTable1 IS SELECT * FROM TABLE1; 

BEGIN 

    --A cursor for the table with the data 
    FOR d1 IN vTable1 
    LOOP 
      --A cursor for the table that store the name of the columns of the table 1 
      FOR v1 IN vTable2 
      LOOP 
      --get the table1 column name 
      vData := v1.table2Col1; 
      --calls the procedure that gives back the value of that record on the column name is stored in VData 
      inst := 'begin getData(:d1, :vData, :vValue); end;'; 


      EXECUTE IMMEDIATE inst USING in d1 , vData, OUT vValue; 

      DBMS_OUTPUT.PUT_LINE(vValue); 

      END LOOP; 

    END LOOP; 

END p1; 

donc, en résumé je veux juste avoir une table qui stocke les noms des table1 dans table2, parce que je veux la procédure de travailler avec une table avec le table1 nom, ce code me donne l'erreur « expression doivent être de SQL types "pour les paramètres du bloc dynamique et je le comprends, mais peut f igure une nouvelle façon de le faire. J'ai essayé beaucoup de choses mais je suis un peu nouveau dans Oracle et j'aurais vraiment apprécié l'aide.

+0

Pourquoi utilisez-vous 'exécuter immediate'? Pourquoi n'appelez-vous pas simplement la fonction 'getData (d1, vData, vValue);'? – San

+0

Pas besoin de SQL dynamique ici. Vois ma réponse. –

+0

On ne sait pas ce que vous essayez d'atteindre, mais un coup d'oeil à [DBMS_SQL] (http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm). Mais dans de nombreux cas, vous n'avez pas besoin de SQL dynamique. –

Répondre

0

inst: = « commencer getData (d1,: vData,: vValeur); fin;';

EXECUTE IMMEDIATE inst UTILISANT en d1, vData, OUT vValeur;

Je ne vois aucune raison pour laquelle vous devez utiliser SQL dynamique ici. Tout ce que vous voulez, c'est de passer le paramètre % ROWTYPE et de le traiter. % ROWTYPE est traité comme RECORD, que vous pourriez utiliser dans le programme PL/SQL.

Par exemple,

SQL> CREATE OR REPLACE 
    2 FUNCTION func(
    3  i_dept IN NUMBER, 
    4  i_emp_rec IN emp%rowtype) 
    5  RETURN VARCHAR2 
    6 IS 
    7 BEGIN 
    8  RETURN 'DEPTNO = ' || i_dept || ' ENAME = ' || i_emp_rec.ename; 
    9 END; 
10/

Function created. 

SQL> 
SQL> SET serveroutput ON 
SQL> DECLARE 
    2 v_deptno dept.deptno%type; 
    3 cur sys_refcursor; 
    4 v_ecur sys_refcursor; 
    5 v_emp emp%rowtype; 
    6 BEGIN 
    7 OPEN cur FOR SELECT d.deptno, 
    8 CURSOR 
    9  (SELECT e.* FROM emp e WHERE e.deptno = d.deptno 
10  ) e FROM dept d; 
11 LOOP 
12  FETCH cur INTO v_deptno, v_ecur; 
13  EXIT 
14 WHEN cur%notfound; 
15  LOOP 
16  FETCH v_ecur INTO v_emp; 
17  EXIT 
18  WHEN v_ecur%notfound; 
19  dbms_output.put_line(func(v_deptno,v_emp)); 
20  END LOOP; 
21  CLOSE v_ecur; 
22 END LOOP; 
23 CLOSE cur; 
24 END; 
25/
DEPTNO = 10 ENAME = CLARK 
DEPTNO = 10 ENAME = KING 
DEPTNO = 10 ENAME = MILLER 
DEPTNO = 20 ENAME = SMITH 
DEPTNO = 20 ENAME = JONES 
DEPTNO = 20 ENAME = SCOTT 
DEPTNO = 20 ENAME = ADAMS 
DEPTNO = 20 ENAME = FORD 
DEPTNO = 30 ENAME = ALLEN 
DEPTNO = 30 ENAME = WARD 
DEPTNO = 30 ENAME = MARTIN 
DEPTNO = 30 ENAME = BLAKE 
DEPTNO = 30 ENAME = TURNER 
DEPTNO = 30 ENAME = JAMES 

PL/SQL procedure successfully completed. 

SQL>