create or replace PROCEDURE BUILDREPORT_sql_performance
(
userChoice IN INT
) AS
BEGIN
DELETE FROM TMP_sql_performance;
INSERT INTO TMP_sql_performance
(sql_text,
sql_fulltext,
cpu_time,
last_load_time)
(SELECT sql_text, sql_fulltext, cpu_time,
last_load_time from v$sql
WHERE (CASE
WHEN userChoice = 3 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > ADD_MONTHS(TRUNC(SYSDATE), -12) THEN 1 --One Year
WHEN userChoice = 2 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > ADD_MONTHS(TRUNC(SYSDATE), -1) THEN 1 --One Month
WHEN userChoice = 1 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > TRUNC(SYSDATE -7) THEN 1 --One Week
WHEN userChoice = 0 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > TRUNC(SYSDATE -1) THEN 1 --one Day
ELSE 0
END) = 1);
select * from tmp_sql_performance;
END BUILDREPORT_sql_performance;
它给了我:错误(24,3):PLS-00428:在这个SELECT语句中需要一个INTO子句。可能我只能在程序中查询一次或两次
答案 0 :(得分:0)
你必须选择一些东西,它必须是一个变量,记录或集合(取决于你得到的数据 - 列数和行数)。或者你可以有一个迭代的游标并做一些事情(包括可能,仅用于调试目的,使用dbms_output
进行记录)。
听起来您想要将查询结果返回给过程调用者,您可以使用ref cursor OUT parameter执行此操作:
create or replace PROCEDURE BUILDREPORT_sql_performance
(
userChoice IN INT,
resultCursor OUT SYS_REFCURSOR
) AS
BEGIN
DELETE FROM TMP_sql_performance;
INSERT INTO TMP_sql_performance
(sql_text,
sql_fulltext,
cpu_time,
last_load_time)
(SELECT sql_text, sql_fulltext, cpu_time,
last_load_time from v$sql
WHERE (CASE
WHEN userChoice = 3 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > ADD_MONTHS(TRUNC(SYSDATE), -12) THEN 1 --One Year
WHEN userChoice = 2 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > ADD_MONTHS(TRUNC(SYSDATE), -1) THEN 1 --One Month
WHEN userChoice = 1 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > TRUNC(SYSDATE -7) THEN 1 --One Week
WHEN userChoice = 0 AND TO_DATE(substr(last_load_time, 1, 10),'YYYY-MM-DD') > TRUNC(SYSDATE -1) THEN 1 --one Day
ELSE 0
END) = 1);
OPEN resultCursor FOR
select * from tmp_sql_performance;
END BUILDREPORT_sql_performance;
/
然后对过程的调用需要传递sys_refcursor
变量,并对生成的游标执行某些操作。
出于测试目的,您可以使用匿名块,以及 - 在SQL * Plus和SQL Developer中的leats - 客户端定义的绑定变量:
variable rc refcursor
exec buildreport_sql_performance(42, :rc);
print rc
exec
是匿名阻止的简写,因此与执行操作相同:
begin
buildreport_sql_performance(42, :rc);
end;
/
注意过程调用中:rc
之前的冒号。这表示您正在传递一个在外部 PL / SQL块中定义的绑定变量。
variable
和print
命令是Oracle客户端命令,而不是SQL。其他客户端可能无法识别它们,尽管有些客户端模仿了Oracle的行为。
你说“每当我执行该程序时,它必须向我显示更新的表格”。这取决于执行它的任何人或任何人。您无法直接从PL / SQL显示任何内容 - 它实际上并不是设计为交互式语言。您可能最终通过JDBC从Java程序中调用它,然后将使用Java代码迭代结果集并对每行中的值执行某些操作。或者它可以从其他PL / SQL或预定作业调用,或者在其他地方没有逻辑位置来显示输出。在上面的示例中,客户端程序正在调用过程并显示OUT游标,但仅在明确告知时才会显示。
正如Justin Cave所指出的那样,你正在做的事情似乎是试图模仿另一个数据库系统中的行为。你真的需要一个(可能是全局临时的)表并不明显;您可以在打开光标时直接查询v$sql
:
create or replace procedure buildreport_sql_performance
(
userchoice in int,
resultcursor out sys_refcursor
) as
begin
open resultcursor for
select sql_text, sql_fulltext, cpu_time, last_load_time from v$sql
where (case
when userchoice = 3 and to_date(substr(last_load_time, 1, 10),'YYYY-MM-DD') > add_months(trunc(sysdate), -12) then 1 --One Year
when userchoice = 2 and to_date(substr(last_load_time, 1, 10),'YYYY-MM-DD') > add_months(trunc(sysdate), -1) then 1 --One Month
when userchoice = 1 and to_date(substr(last_load_time, 1, 10),'YYYY-MM-DD') > trunc(sysdate -7) then 1 --One Week
when userchoice = 0 and to_date(substr(last_load_time, 1, 10),'YYYY-MM-DD') > trunc(sysdate -1) then 1 --one Day
else 0
end) = 1;
end buildreport_sql_performance;
/
或者没有重复to_date()
来电:
create or replace procedure buildreport_sql_performance
(
userchoice in int,
resultcursor out sys_refcursor
) as
begin
open resultcursor for
select sql_text, sql_fulltext, cpu_time, last_load_time from v$sql
where to_date(substr(last_load_time, 1, 10),'YYYY-MM-DD') > case
when userchoice = 3 then add_months(trunc(sysdate), -12) --One Year
when userchoice = 2 then add_months(trunc(sysdate), -1) --One Month
when userchoice = 1 then trunc(sysdate -7) --One Week
when userchoice = 0 then trunc(sysdate -1) --one Day
else null
end;
end buildreport_sql_performance;
/