"ORA-01007: variable not in select list" 当 EXECUTE IMMEDIATE 没有返回任何行时
"ORA-01007: variable not in select list" when no rows are returned by EXECUTE IMMEDIATE
我有一个过程接收一个 where 子句作为参数(即 where col1 = 1
)。我正在使用此子句使用 EXECUTE IMMEDIATE 语句在某些 table 中进行搜索,并将结果插入到嵌套的 table 中,然后再显示出来。
如果找到任何数据,程序运行正常,但如果没有找到数据,则会抛出上述错误。
请问有人能解释一下是什么原因导致这个错误吗?
程序如下:
create or replace procedure prc_checks(pi_where varchar2) as
cursor c_tables is
select object_name,
case object_name
when 'XP_IMPORT_MW' THEN 99999999
when 'XP_IMPORT_MW_ARCH' THEN 99999998
else TO_NUMBER(SUBSTR(object_name, -8, 8))
end to_order
from dba_objects
where object_type = 'TABLE'
and object_name IN ('XP_IMPORT_MW', 'XP_IMPORT_MW_ARCH')
or REGEXP_LIKE (object_name, 'XP_IMPORT_MW_ARCH_201(5|6|7)[0-9]{4}') order by 2 desc;
type t_result is table of xp_import_mw%rowtype;
v_result t_result;
v_sql varchar2(300);
BEGIN
for i in c_tables
loop
v_sql := 'select * from ' || i.object_name || ' ' || pi_where;
execute immediate v_sql bulk collect into v_result;
if v_result.count > 0
then
for j in v_result.first .. v_result.last
loop
dbms_output.put_line(v_result(j).art_nr);
end loop;
dbms_output.put_line('... the required information was found on table name ' || upper(i.object_name));
exit;
end if;
end loop;
END prc_checks;
你会得到这是游标发现的 table 之一,其列数少于 xp_import_mw
。例如:
create table xp_import_mw (col1 number, art_nr number, dummy number);
create table xp_import_mw_arch_20160102 (col1 number, art_nr number, dummy number);
create table xp_import_mw_arch_20160101 (col1 number, art_nr number);
insert into xp_import_mw_arch_20160101 values (1, 42);
所以主 xp_import_mw
table 有三列但没有匹配的数据。旧存档之一 tables 少了一列。
我在程序中添加了一个 dbms_output.put_line(v_sql)
以查看它对哪个 table 失败,然后 运行 它:
set serveroutput on
exec prc_checks('where col1 = 1');
得到输出:
select * from XP_IMPORT_MW where col1 = 1
select * from XP_IMPORT_MW_ARCH_20160102 where col1 = 1
select * from XP_IMPORT_MW_ARCH_20160101 where col1 = 1
Error starting at line : 49 in command -
BEGIN prc_checks('where col1 = 1'); END;
Error report -
ORA-01007: variable not in select list
ORA-06512: at "MY_SCHEMA.PRC_CHECKS", line 25
ORA-06512: at line 1
01007. 00000 - "variable not in select list"
*Cause:
*Action:
所以问题不是没有找到数据,而是没有找到数据。问题是 是 在结构错误的 table 中匹配的数据。
您可以根据 xp_import_mw
table 的结构构建 select 列表,而不是使用 *
;这不会阻止它失败,但至少会给你一个稍微有用的错误消息 - 在这种情况下 ORA-00904: "DUMMY": invalid identifier
而不是 ORA-01007.
您可以快速粗略地检查是否存在差异,例如:
select table_name, count(column_id) as column_count,
listagg(column_name, ',') within group (order by column_id) as columns
from dba_tab_columns
where table_name IN ('XP_IMPORT_MW', 'XP_IMPORT_MW_ARCH')
or REGEXP_LIKE (table_name, 'XP_IMPORT_MW_ARCH_201(5|6|7)[0-9]{4}')
group by table_name
having count(column_id) != (
select count(column_id) from dba_tab_columns where table_name = 'XP_IMPORT_MW'
);
...尽管如果您使用的是 dba_*
或 all_*
视图,您真的应该在此处和您的程序中包括所有者。
我有一个过程接收一个 where 子句作为参数(即 where col1 = 1
)。我正在使用此子句使用 EXECUTE IMMEDIATE 语句在某些 table 中进行搜索,并将结果插入到嵌套的 table 中,然后再显示出来。
如果找到任何数据,程序运行正常,但如果没有找到数据,则会抛出上述错误。
请问有人能解释一下是什么原因导致这个错误吗?
程序如下:
create or replace procedure prc_checks(pi_where varchar2) as
cursor c_tables is
select object_name,
case object_name
when 'XP_IMPORT_MW' THEN 99999999
when 'XP_IMPORT_MW_ARCH' THEN 99999998
else TO_NUMBER(SUBSTR(object_name, -8, 8))
end to_order
from dba_objects
where object_type = 'TABLE'
and object_name IN ('XP_IMPORT_MW', 'XP_IMPORT_MW_ARCH')
or REGEXP_LIKE (object_name, 'XP_IMPORT_MW_ARCH_201(5|6|7)[0-9]{4}') order by 2 desc;
type t_result is table of xp_import_mw%rowtype;
v_result t_result;
v_sql varchar2(300);
BEGIN
for i in c_tables
loop
v_sql := 'select * from ' || i.object_name || ' ' || pi_where;
execute immediate v_sql bulk collect into v_result;
if v_result.count > 0
then
for j in v_result.first .. v_result.last
loop
dbms_output.put_line(v_result(j).art_nr);
end loop;
dbms_output.put_line('... the required information was found on table name ' || upper(i.object_name));
exit;
end if;
end loop;
END prc_checks;
你会得到这是游标发现的 table 之一,其列数少于 xp_import_mw
。例如:
create table xp_import_mw (col1 number, art_nr number, dummy number);
create table xp_import_mw_arch_20160102 (col1 number, art_nr number, dummy number);
create table xp_import_mw_arch_20160101 (col1 number, art_nr number);
insert into xp_import_mw_arch_20160101 values (1, 42);
所以主 xp_import_mw
table 有三列但没有匹配的数据。旧存档之一 tables 少了一列。
我在程序中添加了一个 dbms_output.put_line(v_sql)
以查看它对哪个 table 失败,然后 运行 它:
set serveroutput on
exec prc_checks('where col1 = 1');
得到输出:
select * from XP_IMPORT_MW where col1 = 1
select * from XP_IMPORT_MW_ARCH_20160102 where col1 = 1
select * from XP_IMPORT_MW_ARCH_20160101 where col1 = 1
Error starting at line : 49 in command -
BEGIN prc_checks('where col1 = 1'); END;
Error report -
ORA-01007: variable not in select list
ORA-06512: at "MY_SCHEMA.PRC_CHECKS", line 25
ORA-06512: at line 1
01007. 00000 - "variable not in select list"
*Cause:
*Action:
所以问题不是没有找到数据,而是没有找到数据。问题是 是 在结构错误的 table 中匹配的数据。
您可以根据 xp_import_mw
table 的结构构建 select 列表,而不是使用 *
;这不会阻止它失败,但至少会给你一个稍微有用的错误消息 - 在这种情况下 ORA-00904: "DUMMY": invalid identifier
而不是 ORA-01007.
您可以快速粗略地检查是否存在差异,例如:
select table_name, count(column_id) as column_count,
listagg(column_name, ',') within group (order by column_id) as columns
from dba_tab_columns
where table_name IN ('XP_IMPORT_MW', 'XP_IMPORT_MW_ARCH')
or REGEXP_LIKE (table_name, 'XP_IMPORT_MW_ARCH_201(5|6|7)[0-9]{4}')
group by table_name
having count(column_id) != (
select count(column_id) from dba_tab_columns where table_name = 'XP_IMPORT_MW'
);
...尽管如果您使用的是 dba_*
或 all_*
视图,您真的应该在此处和您的程序中包括所有者。