【问题标题】:Dynamic parameters not sql types Oracle动态参数不是 sql 类型 Oracle
【发布时间】:2015-02-25 07:29:15
【问题描述】:

我正在尝试做这样的事情:

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;

将记录和列名作为参数并返回值的过程:

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;

所以总而言之,我只想有一个表,将表 1 的名称存储在表 2 中,因为我希望该过程与名称为表 1 的任何表一起使用,这段代码给了我错误“表达式必须是SQL types”用于动态块的参数,我理解它,但可以找到一种新的方法来做到这一点。我已经尝试了很多东西,但我是 Oracle 的新手,非常感谢您的帮助。

【问题讨论】:

  • 你为什么使用execute immediate?为什么不直接调用函数getData(d1,vData,vValue);
  • 这里不需要动态SQL。看我的回答。
  • 不清楚你想达到什么目标,但是看看DBMS_SQL。但在很多情况下,您不需要动态 SQL。
  • 你能编译你的函数getData吗?
  • 嗨,没有函数 getData 说必须声明组件 col1 我假设这是因为 col1 它不是列的名称,而是包含列名称的变量。 @Polppan

标签: oracle plsql record dynamic-programming rowtype


【解决方案1】:

inst := '开始获取数据(:d1, :vData, :vValue );结束;';

在 d1、vData、OUT vValue 中立即执行 inst 使用;

我看不出您需要在此处使用 动态 SQL 的任何理由。你想要的只是传递 %ROWTYPE 参数并处理它。 %ROWTYPE 被视为 RECORD,您可以在 PL/SQL 程序中使用它。

例如,

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>

【讨论】:

    猜你喜欢
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多