Oracle PL/SQL输出一个字符串和一个带有execute immediate的数字
我对PL/SQL非常陌生,我试图找出哪些列不用于表中的哪种类型。 这意味着我有这样的东西:Oracle PL/SQL输出一个字符串和一个带有execute immediate的数字,oracle,plsql,Oracle,Plsql,我对PL/SQL非常陌生,我试图找出哪些列不用于表中的哪种类型。 这意味着我有这样的东西: ____________________ ... ________ | A | B | C | ... Type | |______|_____|______| ... ________| |(null)| val | val | ... 1 | |(null)| val | val | 2 JOINS
____________________ ... ________
| 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(即使是,它是一次性任务并且已经完成;)):)