简体   繁体   中英

How to use column name dynamically with bulk collect

How can I use columns dynamically with bulk collect?

The code shown here is throwing errors:

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;

Error report:

ORA-06550: line 15, column 7:
PLS-00306: wrong number or types of arguments in call to '||'

r_emp is an array and not an array or arrays so you cannot BULK COLLECT INTO r_emp(i) , instead, you need to BULK COLLECT INTO r_emp (and need to neither initialise nor extend it as that is done automatically by BULK COLLECT ).

You also cannot concatenate a string with a VARRAY so 'SELECT '||t_emp will not work (and is where your error message comes from). Instead, you can concatenate two strings so 'SELECT '||t_emp(1) would work.

And you cannot initialise a SYS.ODCINUMBERLIST with the value 'CUST_ID' as it is a string and not a number.

Instead, you can use:

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;
/

Which, for the sample data:

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;

Outputs:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM