oracle 如何在批量收集中动态使用列名

xxslljrj  于 2022-11-28  发布在  Oracle
关注(0)|答案(1)|浏览(230)

如何在大容量收集中动态使用列?
此处显示的代码引发错误:

SET serverout ON 

DECLARE
  r_emp   SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST();
  t_emp   SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST('CUST_ID');
  v_array SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST(

'CUST_TYPE',
'CERT_TYPE_NAME',
'CERT_NBR',
'NEW_PARENT_CUST_ID');
BEGIN
  DBMS_OUTPUT.ENABLE;
  FOR i IN 1..v_array.COUNT LOOP
  r_emp.extend;
    EXECUTE IMMEDIATE
      'SELECT '||t_emp||'  FROM CUSTOMER_PROFILE where '||v_array(i)||' is null'
      BULK COLLECT INTO r_emp(i);
      for k in 1..r_emp(i).count loop
    dbms_output.put_line(v_array(i) || ': ' || r_emp(k));
    end loop;
  END LOOP;
END;

错误报告:
ORA-06550:第15行,第7列:
PLS-00306:调用'时参数的数量或类型错误||'

gcuhipw9

gcuhipw91#

r_emp是一个数组,而不是一个数组或数组,所以你不能BULK COLLECT INTO r_emp(i),相反,你需要BULK COLLECT INTO r_emp(不需要初始化或扩展它,因为这是由BULK COLLECT自动完成的)。
您也不能将字符串与VARRAY连接起来,这样'SELECT '||t_emp就无法工作(您的错误信息就是从这里产生的)。相反,您可以将两个字符串连接起来,这样'SELECT '||t_emp(1)就可以工作。
你不能用'CUST_ID'初始化一个SYS.ODCINUMBERLIST,因为它是一个字符串而不是一个数字。
相反,您可以使用:

DECLARE
  r_emp   SYS.ODCINUMBERLIST;
  t_emp   SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST('CUST_ID');
  v_array SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST(
    'CUST_TYPE',
    'CERT_TYPE_NAME',
    'CERT_NBR',
    'NEW_PARENT_CUST_ID'
  );
BEGIN
  DBMS_OUTPUT.ENABLE;
  FOR i IN 1..v_array.COUNT LOOP
    FOR j IN 1..t_emp.COUNT LOOP
      EXECUTE IMMEDIATE
        'SELECT '||t_emp(j)||'  FROM CUSTOMER_PROFILE where '||v_array(i)||' is null'
        BULK COLLECT INTO r_emp;
      FOR k IN 1..r_emp.COUNT LOOP
        dbms_output.put_line(v_array(i) || ': ' || r_emp(k));
      END LOOP;
    END LOOP;
  END LOOP;
END;
/

其中,对于示例数据:

create table customer_profile (
  cust_id            NUMBER,
  cust_type          VARCHAR2(20),
  cert_type_name     VARCHAR2(20),
  cert_nbr           VARCHAR2(20),
  new_parent_cust_id VARCHAR2(20)
);

INSERT INTO customer_profile
  SELECT 1, NULL, 'a', 'a', 'a' FROM DUAL UNION ALL
  SELECT 2, 'b', NULL, 'b', 'b' FROM DUAL UNION ALL
  SELECT 3, 'c', 'c', NULL, 'c' FROM DUAL UNION ALL
  SELECT 4, 'd', 'd', 'd', NULL FROM DUAL UNION ALL
  SELECT 5, NULL, NULL, NULL, NULL FROM DUAL;

输出:

CUST_TYPE: 1
CUST_TYPE: 5
CERT_TYPE_NAME: 2
CERT_TYPE_NAME: 5
CERT_NBR: 3
CERT_NBR: 5
NEW_PARENT_CUST_ID: 4
NEW_PARENT_CUST_ID: 5

fiddle

相关问题