我正在尝试使用用户参数在Oracle Apex中生成报告。首先,我有一个表格,用户可以选择频率,日期,要报告的人以及其他选项。我会将所有这些详细信息发送到呈现此交互式报告的下一页。到目前为止,我一直在尝试在PL / SQL Function主体中构建查询以返回SQL查询,但是每次我都收到以下错误时。
ORA-20999:WWV_FLOW_EXEC.NULL_QUERY_RETURNED_BY_FUNCTION
我的代码示例:
declare
single_date char(12) := ''''||TO_CHAR(TRUNC(to_date(:P21_DATE, 'DD-MM-YYYY')), 'DD.MM.YYYY')||'''';
start_date_value char(12) := ''''||TO_CHAR(TRUNC(to_date(:P21_DATE, 'DD-MM-YYYY'), 'IW'), 'DD.MM.YYYY')||'''';
end_date_value char(12) := ''''||TO_CHAR(TRUNC(to_date(:P21_DATE, 'DD-MM-YYYY'), 'IW') + 6, 'DD.MM.YYYY')||'''';
first_month_value char(12) := ''''||to_char(trunc(to_date(:P21_DATE, 'DD-MM-YYYY'), 'MM'), 'DD.MM.YYYY')||'''';
last_month_value char(12) := ''''||to_char(LAST_DAY(to_date(:P21_DATE,'DD-MM-YYYY')), 'DD.MM.YYYY')||'''';
first_year_value char(12) := ''''||to_char(trunc(to_date(:P21_DATE, 'DD-MM-YYYY'), 'YYYY'), 'DD.MM.YYYY')||'''';
last_year_value char(12) := ''''||to_char(last_day(add_months(to_date(:P21_DATE,'DD-MM-YYYY'),12 - to_number(to_char(to_date(:P21_DATE,'DD-MM-YYYY'),'mm')))), 'DD.MM.YYYY')||'''';
begin
if :P21_DETAILS = 1 then
if :P21_FREQUENCY = 1 then
if :P21_FOR = 1 then
return q'~
SELECT <columns> FROM <table> WHERE <date> = '||single_date||' AND <something> = '||lower(:APP_USER)||';
~';
elsif :P21_FOR = 2 then
return q'~
SELECT <columns> FROM <table> WHERE <date> = '||single_date||' AND <something> = '||lower(:P21_PERSON)||';
~';
elsif :P21_FOR = 3 then
return q'~
SELECT <columns> FROM <table> WHERE <date> = '||single_date||';
~';
end if;
elsif :P21_FREQUENCY = 2 then
if :P21_FOR = 1 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||start_date_value||', ''DD.MM.YYYY'') AND TO_DATE('||end_date_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:APP_USER)||';
~';
elsif :P21_FOR = 2 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||start_date_value||', ''DD.MM.YYYY'') AND TO_DATE('||end_date_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:P21_PERSON)||';
~';
elsif :P21_FOR = 3 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||start_date_value||', ''DD.MM.YYYY'') AND TO_DATE('||end_date_value||', ''DD.MM.YYYY'');
~';
end if;
elsif :P21_FREQUENCY = 3 then
if :P21_FOR = 1 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_month_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_month_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:APP_USER)||';
~';
elsif :P21_FOR = 2 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_month_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_month_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:P21_PERSON)||';
~';
elsif :P21_FOR = 3 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_month_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_month_value||', ''DD.MM.YYYY'');
~';
end if;
elsif :P21_FREQUENCY = 4 then
if :P21_FOR = 1 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_year_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_year_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:APP_USER)||';
~';
elsif :P21_FOR = 2 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_year_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_year_value||', ''DD.MM.YYYY'') AND <something> = '||lower(:P21_PERSON)||';
~';
elsif :P21_FOR = 3 then
return q'~
SELECT <columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_year_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_year_value||', ''DD.MM.YYYY'');
~';
end if;
end if;
end if;
end;
还尝试了其他方法,在下面进行编码,但也没有成功。
ORA-01403:找不到数据
declare
date_modify char(12) := :P24_DATE;
single_date char(12) := ''''||TO_CHAR(TRUNC(to_date(date_modify, 'DD.MM.YYYY')), 'DD.MM.YYYY')||'''';
start_date_value char(12) := ''''||TO_CHAR(TRUNC(to_date(date_modify, 'DD.MM.YYYY'), 'IW'), 'DD.MM.YYYY')||'''';
end_date_value char(12) := ''''||TO_CHAR(TRUNC(to_date(date_modify, 'DD.MM.YYYY'), 'IW') + 6, 'DD.MM.YYYY')||'''';
first_month_value char(12) := ''''||to_char(trunc(to_date(date_modify, 'DD.MM.YYYY'), 'MM'), 'DD.MM.YYYY')||'''';
last_month_value char(12) := ''''||to_char(LAST_DAY(to_date(date_modify,'DD.MM.YYYY')), 'DD.MM.YYYY')||'''';
first_year_value char(12) := ''''||to_char(trunc(to_date(date_modify, 'DD.MM.YYYY'), 'YYYY'), 'DD.MM.YYYY')||'''';
last_year_value char(12) := ''''||to_char(last_day(add_months(to_date(date_modify,'DD.MM.YYYY'),12 - to_number(to_char(to_date(date_modify,'DD.MM.YYYY'),'mm')))), 'DD.MM.YYYY')||'''';
query varchar2(500);
begin
if apex_application.g_f01(1) = 1 then
if :P24_TYPE = 1 then
query := 'SELECT <some columns> FROM <table> WHERE <date> = '||single_date||'';
elsif :P24_TYPE = 2 then
query := 'SELECT <some columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||start_date_value||', ''DD.MM.YYYY'') AND TO_DATE('||end_date_value||', ''DD.MM.YYYY'')';
elsif :P24_TYPE = 3 then
query := 'SELECT <some columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_month_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_month_value||', ''DD.MM.YYYY'')';
elsif :P24_TYPE = 4 then
query := 'SELECT <some columns> FROM <table> WHERE <date> BETWEEN TO_DATE('||first_year_value||', ''DD.MM.YYYY'') AND TO_DATE('||last_year_value||', ''DD.MM.YYYY'')';
end if;
end if;
if :P24_PERSON <> 'no' then
query := query||' AND <something_else> = '''||lower(:P24_PERSON)||'''';
end if;
return query;
end;
谢谢。
答案 0 :(得分:1)
考虑到过去和逻辑问题,您的代码当前是一场SQL injection的噩梦,使您的页面容易受到用户查询他们不允许的信息的攻击。它还强制使用文字,这会太快破坏您共享的SQL,forcing hard parsing.
具有本机功能,可让您使用IR链接到页面,并像手动使用过滤器一样预先填充过滤器。
https://docs.oracle.com/database/apex-5.1/HTMDB/linking-to-interactive-reports.htm#HTMDB30108