oracle 我如何使用我的代码从表中获得列数?

tv6aics1  于 2022-11-22  发布在  Oracle
关注(0)|答案(3)|浏览(98)
      • v _ array 中 的 这些 列 有 计数 , 但是 当 我 运行 这 段 代码 时 , 它 对 所有 列 返回 零 计数 , 我 的 错误 在 哪里 , 请 帮助 我 - - - -
set serveroutput on
     declare 
            type t_list is table of varchar(50) index by PLS_INTEGER;
            r_emp t_list;
            type e_list is varray(4) of varchar(50);
            v_array e_list;
            begin
            v_array:=e_list('CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE');
            for i in 1..4 loop
            select  sum(case when v_array(i) is null then 1 else 0 end) into r_emp(i) from SZ_GOODS_DETAIL;
             dbms_output.put_line( r_emp(i));
             end loop;
             end;


--------------output--------------------
0
0
0
0

PL/SQL procedure successfully completed.

中 的 每 一 个

wko9yo5t

wko9yo5t1#

您似乎在尝试计算集合中包含的每个列中的空值的数量。当您这样做时:

select  sum(case when v_array(i) is null then 1 else 0 end) into r_emp(i) from SZ_GOODS_DETAIL;

您正在计算表中 * 集合元素 * v_array(i)为空的行数--它要么总是为零(如果集合元素不为空,就像您的所有元素一样),要么是表中的行数(如果元素为空)。该元素是否为空与表中的数据无关。
如果您要针对表格中的每一个数据列,评估与该收集要素值Map的数据栏值,则您必须使用下列方式来评估要素名称:

select sum(case
      when v_array(i) = 'CLAIRTY_ID' and CLAIRTY_ID is null then 1
      when v_array(i) = 'SERV_ACCT_NUMBER' and SERV_ACCT_NUMBER is null then 1
      when v_array(i) = 'BB_ACQUISITION_TYPE' and BB_ACQUISITION_TYPE is null then 1
      when v_array(i) = 'ONT_ACQ_TYPE' and ONT_ACQ_TYPE is null then 1
      else 0
    end)
    into r_emp(i)

...这使得集合有点无意义,可能不是您所想的那样,或者使用动态SQL将元素值嵌入为列名:

declare 
  type t_list is table of number index by PLS_INTEGER;
  r_emp t_list;
  type e_list is varray(4) of varchar2(50);
  v_array e_list;
  v_stmt varchar2(255);
begin
  v_array:=e_list('CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE');
  for i in 1..4 loop
    v_stmt := 'select sum(case when "' || v_array(i) || '" is null then 1 else 0 end) from SZ_GOODS_DETAIL';
    -- just for debugging
    dbms_output.put_line(v_stmt);
    execute immediate v_stmt into r_emp(i);
    dbms_output.put_line(r_emp(i));
  end loop;
end;
/

循环的每次迭代都将构造并执行一个动态语句,如下所示:

select sum(case when "CLAIRTY_ID" is null then 1 else 0 end) from SZ_GOODS_DETAIL

...您可以在调试输出中看到它(一旦它工作,您显然可以删除它)。
您也可以使用count()进行计算,从数据列数中减去非Null值的数目:

v_stmt := 'select count(*) - count("' || v_array(i) || '") from SZ_GOODS_DETAIL';

或者,您可以避免使用PL/SQL,而使用XML技巧:

select column_value,
  to_number(xmlquery('/ROWSET/ROW/C/text()'
    passing xmltype(dbms_xmlgen.getxml(
      'select count(case when "' || column_value || '" is null then 1 end) as c '
      || 'from SZ_GOODS_DETAIL'))
  returning content)) as c
from sys.odcivarchar2list('CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE')

fiddle

uqxowvwt

uqxowvwt2#

您希望得到什么结果?SZ_GOODS_DETAIL表与它有什么关系?我猜您希望将集合内容与存储在该表中的值进行比较,但是-您的代码没有这样做。
以下是我 * 认为 * 你想要的(不一定是真的):
表格内容:

SQL> SELECT * FROM sz_goods_detail;

        ID NAME
---------- -------------------
         1 CLAIRTY_ID
         2 CLAIRTY_ID
         3 BB_ACQUISITION_TYPE

SQL> SET SERVEROUTPUT ON

修改程序(参见第19行):

SQL> DECLARE
  2     TYPE t_list IS TABLE OF VARCHAR (50)
  3        INDEX BY PLS_INTEGER;
  4
  5     r_emp    t_list;
  6
  7     TYPE e_list IS VARRAY (4) OF VARCHAR (50);
  8
  9     v_array  e_list;
 10  BEGIN
 11     v_array :=
 12        e_list ('CLAIRTY_ID',
 13                'SERV_ACCT_NUMBER',
 14                'BB_ACQUISITION_TYPE',
 15                'ONT_ACQ_TYPE');
 16
 17     FOR i IN 1 .. 4
 18     LOOP
 19        SELECT SUM (CASE WHEN v_array (i) = s.name THEN 1 ELSE 0 END)
 20          INTO r_emp (i)
 21          FROM sz_goods_detail s;
 22
 23        DBMS_OUTPUT.put_line (v_array(i) ||': '|| r_emp (i));
 24     END LOOP;
 25  END;
 26  /

结果:

CLAIRTY_ID: 2
SERV_ACCT_NUMBER: 0
BB_ACQUISITION_TYPE: 1
ONT_ACQ_TYPE: 0

PL/SQL procedure successfully completed.

SQL>
t9eec4r0

t9eec4r03#

如果 要 使用 动态 列名 , 则 需要 使用 动态 SQL :

DECLARE
  r_emp   SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST();
  v_array SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST(
     'CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE'
  );
BEGIN
  DBMS_OUTPUT.ENABLE;
  FOR i IN 1..v_array.COUNT LOOP
    r_emp.EXTEND;
    EXECUTE IMMEDIATE
      'SELECT SUM(CASE WHEN "' || v_array(i) || '" IS NULL THEN 1 ELSE 0 END) FROM SZ_GOODS_DETAIL'
      INTO r_emp(i);
    dbms_output.put_line(v_array(i) || ': ' || r_emp(i));
  END LOOP;
END;
/

中 的 每 一 个
其中 , 对于 示例 数据 :

CREATE TABLE SZ_GOODS_DETAIL (CLAIRTY_ID, SERV_ACCT_NUMBER, BB_ACQUISITION_TYPE, ONT_ACQ_TYPE) AS
SELECT 1, 1,    1,    1    FROM DUAL UNION ALL
SELECT 1, 1,    1,    NULL FROM DUAL UNION ALL
SELECT 1, 1,    NULL, NULL FROM DUAL UNION ALL
SELECT 1, NULL, NULL, NULL FROM DUAL;

格式
输出 :

CLAIRTY_ID: 0
SERV_ACCT_NUMBER: 1
BB_ACQUISITION_TYPE: 2
ONT_ACQ_TYPE: 3

格式
fiddle 的 最 大 值

相关问题