我试图获取一个表的行数,并将其存储在一个变量中,这样我就可以使用该变量了。但是,如果我使用WHERE ROWNUM = 1;,它只会将其存储在变量中,但它只存储数字1,而不是实际的行数。我使用的整个select语句是:
SELECT COUNT(*)
INTO vn_no_tickets
FROM tickets
WHERE ROWNUM = 1;如果我不使用WHERE ROWNUM = 1;,我会得到一个错误"exact fetch返回的行数超过请求的行数“,但是当我使用它时,我只得到了1行,而不是实际的行数。谢谢
编辑:下面是完整的过程
CREATE OR REPLACE PROCEDURE proc_ticket_exp IS
vn_no_tickets NUMBER(4);
vn_ticket_id tickets.ticket_id%TYPE;
vd_exp_date tickets.expiration_date%TYPE;
vc_customer_firstname tickets.customer_firstname%TYPE;
vc_customer_surname tickets.customer_surname%TYPE;
vd_one_week DATE;
vc_fullname VARCHAR2(40);
BEGIN
vd_one_week := sysdate + 7;
SELECT COUNT(*)
INTO vn_no_tickets
FROM tickets
WHERE ROWNUM = 1;
DBMS_OUTPUT.PUT_LINE (vn_no_tickets);
WHILE vn_no_tickets != 0 LOOP
SELECT expiration_date, ticket_id, customer_firstname, customer_surname
INTO vd_exp_date, vn_ticket_id, vc_customer_firstname, vc_customer_surname
FROM tickets
WHERE ROWNUM = vn_no_tickets;
vc_fullname := CONCAT(vc_customer_firstname, CONCAT(' ', vc_customer_surname));
IF vd_exp_date < vd_one_week THEN
DBMS_OUTPUT.PUT_LINE (vc_fullname || 's ticket will expire within one week. Ticket Number: ' || vn_ticket_id);
END IF;
vn_no_tickets := vn_no_tickets - 1;
END LOOP;
END proc_ticket_exp;
/
SHOW ERRORS发布于 2020-05-01 18:34:19
失败的实际代码如下所示,因为在第一个查询中放入rownum=1,你将得到count also as 1,因此你在第一个查询中删除了vn_no_tickets will be 1.If,然后是vn_no_tickets will be greater than 1,下面的查询将是fail
SELECT expiration_date, ticket_id, customer_firstname, customer_surname
INTO vd_exp_date, vn_ticket_id, vc_customer_firstname, vc_customer_surname
FROM tickets
WHERE ROWNUM <= vn_no_tickets;发布于 2020-05-01 18:47:42
ROWNUM上的Oracle documentation非常明确:
条件测试ROWNUM值是否大于正整数始终为false。例如,此查询不返回任何行:
从ROWNUM >1的员工中选择*;
读取的第一行被分配一个值为1的ROWNUM,并使条件为假。要获取的第二行现在是第一行,并且还被分配了ROWNUM 1,并使条件为假。所有行随后都不能满足条件,因此不返回任何行。
(注意:这也适用于大于1的相等比较。)
所以,这个条件:
WHERE ROWNUM = vn_no_tickets仅当vn_no_tickets为"1“时才返回一行。
解决这个问题的最简单方法是省去计数器:
FOR t IN (SELECT expiration_date, ticket_id, customer_firstname, customer_surname
FROM tickets
)
LOOP
vc_fullname := t.customer_firstname || ' ' || t.customer_surname;
IF t.exp_date < vd_one_week THEN
DBMS_OUTPUT.PUT_LINE (vc_fullname || 's ticket will expire within one week. Ticket Number: ' || t.ticket_id);
END IF;
END LOOP; 也就是说,您应该将IF条件移到WHERE子句中。从数据库中检索行是愚蠢的,仅仅是为了检查一个条件--而这个条件一开始就可以用于过滤结果集。
https://stackoverflow.com/questions/61540586
复制相似问题