【问题标题】:Oracle PL/SQL issue: PLS-00306 : wrong number or types of arguments in call toOracle PL/SQL 问题:PLS-00306:调用中的参数数量或类型错误
【发布时间】:2021-11-09 04:54:16
【问题描述】:

今天我的代码出错了

PLS-00306:调用中的参数数量或类型错误

我确保代码工作正常,但是当我在动态代码中使用时不起作用

CREATE OR REPLACE PROCEDURE TB_DATA(P_TB_NAME VARCHAR2)
IS
 V_COLUMNS VARCHAR2(32000) := GET_ALL_COLUMNS(P_TB_NAME) ;
 V_COLUMNS_IN_LOOP VARCHAR2(32000) :=  'I.'||REPLACE ( GET_ALL_COLUMNS(P_TB_NAME) , ',' , '||'',''||I.') ;
 V_FILE UTL_FILE.FILE_TYPE ;
BEGIN

  EXECUTE IMMEDIATE 'DECLARE
  CURSOR C1 IS 
            SELECT '||V_COLUMNS || ' 
            FROM '||P_TB_NAME || ';
               
BEGIN 
' ||V_FILE ||' := UTL_FILE.FOPEN ( ''MY_DIR'' , ''TASK9.CSV'' ,   ''W'' ) ;
    UTL_FILE.PUT_LINE ( '||V_FILE ||' , '|| V_COLUMNS||');
     FOR I IN C1 LOOP 
     UTL_FILE.PUT_LINE ( '||V_FILE ||', '|| V_COLUMNS_IN_LOOP||') ;
     END LOOP ; 
END ;';

END ;

功能:

CREATE OR REPLACE FUNCTION HR.GET_ALL_COLUMNS (P_TABLE VARCHAR2)
RETURN VARCHAR2
IS
  CURSOR C IS 
            SELECT *
            FROM USER_TAB_COLUMNS
            WHERE TABLE_NAME = P_TABLE ;
  CURSOR C1 IS           
            SELECT *
            FROM TAB 
            WHERE TNAME = P_TABLE ;
            
            

V_COLS VARCHAR2(32000); 
V_COLS2 VARCHAR2(32000);       
BEGIN
  FOR I IN C LOOP 
V_COLS :=  V_COLS ||','|| I.COLUMN_NAME  ;
  END LOOP ;
   FOR V IN C1 LOOP 
   V_COLS2  := V_COLS2 ||','|| P_TABLE ;
   END LOOP ;
  
 
  RETURN LTRIM( V_COLS , ',') ;

END ;

我只需要知道我的错误在哪里或缺少什么。

【问题讨论】:

  • GET_ALL_COLUMNS 在您手动测试时是否正常工作?
  • 打印你得到的动态语句并尝​​试将其作为独立语句执行(就像execute immediate 所做的那样)。它会告诉你实际的错误。

标签: oracle plsql


【解决方案1】:

功能正常;它是失败的过程,因为您必须在代码的动态 SQL 部分中声明 V_FILE,而不是在它之外。像这样的:

SQL> CREATE OR REPLACE PROCEDURE TB_DATA (P_TB_NAME VARCHAR2)
  2  IS
  3     V_COLUMNS          VARCHAR2 (32000) := GET_ALL_COLUMNS (P_TB_NAME);
  4     V_COLUMNS_IN_LOOP  VARCHAR2 (32000)
  5        := 'I.' || REPLACE (GET_ALL_COLUMNS (P_TB_NAME), ',', '||'',''||I.');
  6     L_STR              VARCHAR2 (10000);
  7  BEGIN
  8     L_STR :=
  9           'DECLARE
 10    V_FILE UTL_FILE.FILE_TYPE;
 11    CURSOR C1 IS
 12              SELECT '
 13        || V_COLUMNS
 14        || '
 15              FROM '
 16        || P_TB_NAME
 17        || ';
 18  BEGIN
 19       V_FILE := UTL_FILE.FOPEN ( ''MY_DIR'' , ''TASK9.CSV'' ,   ''W'' ) ;
 20       FOR I IN C1 LOOP
 21       UTL_FILE.PUT_LINE ( V_FILE, '
 22        || V_COLUMNS_IN_LOOP
 23        || ') ;
 24       END LOOP ;
 25       UTL_FILE.FCLOSE(V_FILE);
 26  END ;';
 27
 28     EXECUTE IMMEDIATE L_STR;
 29  END;
 30  /

Procedure created.

测试:

SQL> EXEC TB_DATA('DEPT');

PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • 为了详细说明 Littlefoots 的回答,您的代码失败了,因为您连接了一个 UTL_FILE.FILE_TYPE 类型的变量。 || 运算符只接受字符串和 clob 数据。
  • 对;谢谢你,@Koen。我忘了解释错误的原因;在写回复的过程中分心了。
  • 比你晚了几分钟;)
猜你喜欢
  • 2015-09-09
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多