我试图将游标的计数结果放入一个整数,但整数始终保持为0。
DECLARE
v_count int := 0;
CURSOR logins IS
SELECT count(*)
FROM big_table;
BEGIN
OPEN logins;
FETCH logins into v_count;
IF v_count > 10 THEN
DBMS_OUTPUT.PUT_LINE ('Hi mom');
END IF;
CLOSE logins;
END;
这只是我想要执行此操作的代码示例,此提取实际上是在LOOP中。
我尝试在IF语句之前添加“SELECT count(*)INTO v_count ...”。它有效,但速度非常慢。
谢谢!
编辑:正如A.B.Cade所指出的,这个样本有效。所以我的问题可能在我的代码的其他地方,你会发现下面的全部内容:DECLARE
v_hour int := 0;
v_maxConn int;
v_count int;
--set the time parameters
--v_day = the first day you loop in
v_day int := 16;
v_month varchar2 (2) := 10;
v_year varchar2 (4) := 2013;
v_lastDay int := 16;
CURSOR logins IS
SELECT count(*)
FROM (
SELECT (SELECT user_function_name
FROM apps.fnd_form_functions_vl fffv
WHERE (fffv.function_id = a.function_id)) "Current Function",
first_connect,
last_connect,
user_name, session_id,
apps.fnd_profile.value_specific
('ICX_SESSION_TIMEOUT',
a.user_id,
a.responsibility_id,
a.responsibility_application_id,
a.org_id,
NULL
) TIMEOUT,
counter "How many hits a User has made",
a.limit_connects "No of hits allowed in session"
FROM icx.icx_sessions a, fnd_user b
WHERE a.user_id = b.user_id
AND last_connect > SYSDATE - 30
AND b.user_name NOT LIKE 'GUEST'
)
WHERE to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') between first_connect and last_connect
;
out_menu varchar2(500);
out_path varchar2(50) := '/usr/tmp/QA';
file_out utl_file.file_type ;
BEGIN
file_out := utl_file.fopen(out_path,'debug_rapport.txt','W');
OPEN logins;
LOOP EXIT WHEN v_day > v_lastDay;
v_maxConn := 0;
LOOP EXIT WHEN v_hour > 23;
FETCH logins into v_count;
IF v_count > v_maxConn THEN
v_maxConn := v_count;
END IF;
out_menu := 'Debug: ' || to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') || ' -> dateLoop: ' || to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') || ' -> v_maxConn: ' || v_maxConn || ' -> hour:' || v_hour;
utl_file.put_line(file_out,out_menu);
v_hour := v_hour + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE (v_year || '-' || v_month || '-' || v_day || ';' || v_maxConn);
v_hour := 0;
v_day := v_day + 1;
END LOOP;
CLOSE logins;
END;
代码是在给定日期的每个小时内查看并发连接。如果我将BEGIN语句中的游标代码替换为游标中的SELECT语句,它就可以工作。
当我使用光标时,这是我的“Debug”文件的输出:
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:0
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:1
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:2
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:3
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:4
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:5
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:6
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:7
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:8
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:9
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:10
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:11
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:12
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:13
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:14
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:15
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:16
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:17
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:18
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:19
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:20
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:21
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:22
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:23
以下是用“SELECT count(*)INTO v_count [...]”替换光标时的输出:
Debug: 2013-10-24 10:00:40 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:0
Debug: 2013-10-24 10:00:54 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:1
Debug: 2013-10-24 10:01:09 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:2
Debug: 2013-10-24 10:01:23 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:3
Debug: 2013-10-24 10:01:37 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:4
Debug: 2013-10-24 10:01:50 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:5
Debug: 2013-10-24 10:02:05 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:6
Debug: 2013-10-24 10:02:20 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:7
Debug: 2013-10-24 10:02:33 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:8
Debug: 2013-10-24 10:02:47 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:9
Debug: 2013-10-24 10:03:00 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:10
Debug: 2013-10-24 10:03:15 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:11
Debug: 2013-10-24 10:03:28 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:12
Debug: 2013-10-24 10:03:41 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:13
Debug: 2013-10-24 10:03:54 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:14
Debug: 2013-10-24 10:04:08 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:15
Debug: 2013-10-24 10:04:22 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:16
Debug: 2013-10-24 10:04:35 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:17
Debug: 2013-10-24 10:04:47 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:18
Debug: 2013-10-24 10:05:00 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:19
Debug: 2013-10-24 10:05:13 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:20
Debug: 2013-10-24 10:05:25 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:21
Debug: 2013-10-24 10:05:38 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:22
Debug: 2013-10-24 10:05:51 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:23
您看到v_maxConn不会保持为零,因此正在写入v_count。不过,它只用了一天就需要5分钟。
非常感谢您的帮助!
答案 0 :(得分:0)
我稍微修改了你的代码,这可行..
DECLARE
v_count int := 0;
CURSOR logins IS
SELECT count(*)
FROM big_table;
BEGIN
OPEN logins;
loop
FETCH logins into v_count;
IF v_count >= 10 THEN
DBMS_OUTPUT.PUT_LINE ('Hi mom');
exit;
END IF;
end loop;
CLOSE logins;
END;
你忘了循环,结束循环和语句退出,否则会有无限循环...... 希望这可以帮助。如果行数少于10行,则无限循环。
答案 1 :(得分:0)
您正在做一件奇怪的事情 - 您正在v_hour
和v_date
上循环,但您要重新获取同一个只包含一条记录的已打开游标。
所以基本上发生的事情是你一遍又一遍地获得相同的价值(0)
Here is a sqlfiddle demo的样本非常类似于你的情况。
OPEN logins;
for v_i in 1..10 loop
FETCH logins into v_count;
IF v_count > 10 THEN
v_res := v_res ||v_i || '. v_count=' || v_count || ', ';
END IF;
end loop;
CLOSE logins;
如果你真的想这样做,那么你需要在游标中添加一个参数并在每次迭代中重新打开它:
Here is another sample that works
for v_i in 1..10 loop
OPEN logins(v_i);
FETCH logins into v_count;
IF v_count > 10 THEN
v_res := v_res ||v_i || '. v_count=' || v_count || ', ';
END IF;
CLOSE logins;
end loop;
但是,这就像每次尝试中的查询计数(*)(可能会变慢)
很难说,但看起来好像你可以在一个查询中获取值 -
像this
这样的东西答案 2 :(得分:0)
问题在于我没有完全理解游标是如何工作的。我用一个临时表替换了光标,我在其中放置了我的静态查询:
CREATE TABLE apps.audit_custom as
select [...]
然后我在我的LOOP中查询这个表,如下:
SELECT count(*) into v_count
FROM apps.audit_custom
WHERE to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') between first_connect and last_connect;
最后,当我完成时,我放弃了桌子。
这是我发现让我的想法发挥作用的最快方式。
感谢您的帮助!