Oracle PL/SQL输出一个字符串和一个带有execute immediate的数字

Oracle PL/SQL输出一个字符串和一个带有execute immediate的数字,oracle,plsql,Oracle,Plsql,我对PL/SQL非常陌生,我试图找出哪些列不用于表中的哪种类型。 这意味着我有这样的东西: ____________________ ... ________ | A | B | C | ... Type | |______|_____|______| ... ________| |(null)| val | val | ... 1 | |(null)| val | val | 2 JOINS

我对PL/SQL非常陌生,我试图找出哪些列不用于表中的哪种类型。 这意味着我有这样的东西:

 ____________________     ...    ________
|   A  |  B  |  C   |     ...      Type  |
|______|_____|______|     ...    ________|
|(null)| val | val  |     ...       1    |
|(null)| val | val  |   2 JOINS     1    |
|  val | val |(null)|     ...       2    |
|  val | val |(null)|     ...       2    |
|  .   |  .  |   .  |     ...       3    |
|  .   |  .  |   .  |     ...       .    |
|______|_____|______|     ...    ________|
我想要这样的输出:

  for Type 1 : cols used are B, C
  for Type 2 : cols used are A, B
  ... OR
  Col A is used by type 1
  Col B is used by type 1, 2
  Col C is used by type 2
SELECT COUNT(A), Type
FROM enregistrement
INNER JOIN 1
ON idA = idB
INNER JOIN TYPES
ON id1 = id2
WHERE A IS NOT NULL
GROUP BY Type;
declare 
  mytable varchar(32) := 'ENREGISTREMENT';
  cursor s1 (mytable varchar2) is 
            select column_name 
            from user_tab_columns
            where table_name = mytable
            and nullable = 'Y';
  mycolumn varchar2(32);
  query varchar2(100);    
  mycount number;
  type varchar2(10);
begin

  open s1 (mytable);
  loop
     fetch s1 into mycolumn; 
         exit when s1%NOTFOUND;

     query := 'select count('||mycolumn||') FROM ' || mytable 
              || ' INNER JOIN 1 ON idA = idB ' 
              || ' INNER JOIN Type ON id1 = id2 '
              || ' where '  || mycolumn || ' is not null GROUP BY type';

     execute immediate query USING mycount, ficlbl ;

     dbms_output.put_line('Col' || mycolumn || ' is used by ' || type || ' :  ' || mycount );

  end loop;
end; 
  • “Used”表示列中至少有一个结果不为null
  • 我们从2个内部联接得到类型
我一个接一个地这样做:

  for Type 1 : cols used are B, C
  for Type 2 : cols used are A, B
  ... OR
  Col A is used by type 1
  Col B is used by type 1, 2
  Col C is used by type 2
SELECT COUNT(A), Type
FROM enregistrement
INNER JOIN 1
ON idA = idB
INNER JOIN TYPES
ON id1 = id2
WHERE A IS NOT NULL
GROUP BY Type;
declare 
  mytable varchar(32) := 'ENREGISTREMENT';
  cursor s1 (mytable varchar2) is 
            select column_name 
            from user_tab_columns
            where table_name = mytable
            and nullable = 'Y';
  mycolumn varchar2(32);
  query varchar2(100);    
  mycount number;
  type varchar2(10);
begin

  open s1 (mytable);
  loop
     fetch s1 into mycolumn; 
         exit when s1%NOTFOUND;

     query := 'select count('||mycolumn||') FROM ' || mytable 
              || ' INNER JOIN 1 ON idA = idB ' 
              || ' INNER JOIN Type ON id1 = id2 '
              || ' where '  || mycolumn || ' is not null GROUP BY type';

     execute immediate query USING mycount, ficlbl ;

     dbms_output.put_line('Col' || mycolumn || ' is used by ' || type || ' :  ' || mycount );

  end loop;
end; 
注意计数>0的结果,然后通过
B
更改
A
,依此类推

然后我听说了PL/SQL。。。试着这样做:

  for Type 1 : cols used are B, C
  for Type 2 : cols used are A, B
  ... OR
  Col A is used by type 1
  Col B is used by type 1, 2
  Col C is used by type 2
SELECT COUNT(A), Type
FROM enregistrement
INNER JOIN 1
ON idA = idB
INNER JOIN TYPES
ON id1 = id2
WHERE A IS NOT NULL
GROUP BY Type;
declare 
  mytable varchar(32) := 'ENREGISTREMENT';
  cursor s1 (mytable varchar2) is 
            select column_name 
            from user_tab_columns
            where table_name = mytable
            and nullable = 'Y';
  mycolumn varchar2(32);
  query varchar2(100);    
  mycount number;
  type varchar2(10);
begin

  open s1 (mytable);
  loop
     fetch s1 into mycolumn; 
         exit when s1%NOTFOUND;

     query := 'select count('||mycolumn||') FROM ' || mytable 
              || ' INNER JOIN 1 ON idA = idB ' 
              || ' INNER JOIN Type ON id1 = id2 '
              || ' where '  || mycolumn || ' is not null GROUP BY type';

     execute immediate query USING mycount, ficlbl ;

     dbms_output.put_line('Col' || mycolumn || ' is used by ' || type || ' :  ' || mycount );

  end loop;
end; 
抛出一个ORA-06502:(


我甚至不认为这在
executeimmediate
..

中是可能的,动态SQL很难实现,因为编译错误会变成运行时错误

这是无效的SQL;它不会作为SQL运行,因此也不会在PL/SQL中运行:

|| ' INNER JOIN 1 idA = idB '

您需要学习如何用更严厉的眼光看待代码。

这似乎是一个奇怪的要求。但是,可以使用条件聚合计数在SQL中完成,如下所示:

WITH sample_data AS (SELECT NULL a, 10 b, 100 c, 1 TYPE FROM dual UNION ALL
                     SELECT NULL a, 20 b, 120 c, 1 TYPE FROM dual UNION ALL
                     SELECT 20 a, 30 b, NULL c, 2 TYPE FROM dual UNION ALL
                     SELECT 40 a, 40 b, NULL c, 2 TYPE FROM dual UNION ALL
                     SELECT 80 a, NULL b, NULL c, 3 TYPE FROM dual UNION ALL
                     SELECT NULL a, NULL b, NULL c, 4 TYPE FROM dual UNION ALL
                     SELECT 30 a, 10 b, NULL c, 5 TYPE FROM dual UNION ALL
                     SELECT 60 a, 10 b, 3 c, 5 TYPE FROM dual)
-- end of subquery mimicking data in your table. See SQL below:
SELECT TYPE,
       CASE WHEN COUNT(a) > 0 THEN 'Y' END a_col_used,
       CASE WHEN COUNT(b) > 0 THEN 'Y' END b_col_used,
       CASE WHEN COUNT(c) > 0 THEN 'Y' END c_col_used
FROM   sample_data
GROUP BY TYPE
ORDER BY TYPE;

      TYPE A_COL_USED B_COL_USED C_COL_USED
---------- ---------- ---------- ----------
         1            Y          Y
         2 Y          Y          
         3 Y                     
         4                       
         5 Y          Y          Y

如果必须,可以将结果作为串联字符串输出(类似于
选择'for type'| | type | | |'columns use is'| | case when count(a)>0然后是'A',结束| |…
-您可能必须使用rtrim来修剪任何悬垂的
但是:

它有助于显示完整的错误堆栈。一个明显的问题是您的动态SQL有两次'from:
)from'| | mytable
。如何查找名为
from
的表,并给它一个取自
mytable
变量的别名。但可能还有其他问题……对于连接,DB结构比id1=id2更复杂……我简化了它;)而
from
在这里是一个打字错误。。。不在我的代码中:)所以在粘贴到这里之前,您想让我们发现您正在破坏的代码中的语法错误吗?你认为我们怎样才能做到这一点?另外,
ORA-06502
是一个通用的PL/SQL异常。您应该发布整个错误堆栈。简化或修改代码以发布问题是可以的,但前提是它仍然有效-似乎您在发布时引入了分散注意力的错误。再一次,显示您的整个错误堆栈,而不仅仅是不太有用的ORA-06502。我不是在搜索语法校正器。。。谢谢在一般情况下,这更能帮助我。。。我不想复制堆栈中的代码。。我想理解并实现我自己的命令。。。我的错误日志是法文的,所以对你没有帮助…:/这显然很奇怪,但对于一个奇怪的要求,它会起作用。。。但是它让我写了很多拷贝/过去,这就是为什么我尝试用PL/SQL编程的原因。。。别担心我会那样做PS:这是一个奇怪的问题,但它是为了改变BDD的结构,使它更容易所以这只是一个一次性的任务?如果是,如果不想手动键入所有的case表达式,您可以查询用户选项卡\u列并选择文本,例如,
select'case when count('''| column|;name | |)>0,然后从用户选项卡u列中,
我想要的haha thx(即使是,它是一次性任务并且已经完成;)):)