使用显式游标和循环,找不到错误
Posted
技术标签:
【中文标题】使用显式游标和循环,找不到错误【英文标题】:Using explicit cursor and loop, can't find error 【发布时间】:2019-09-28 04:04:55 【问题描述】:我正在尝试找出代码来向 ATA_ENTERTAINER 表中添加一个名为 MORE_THAN_ONE 的新列,其数据类型为 NUMBER(此代码将在 PL/SQL 代码之外)。如果艺人有多个样式类型,则此列将保存其拥有的样式类型的数量(如果有,则在此列中放置 NULL)。
我的代码应该使用明确的光标和循环结构,遍历每个艺人并确定他们拥有的样式数量。如果一个艺人有多个,我需要修改该艺人的 MORE_THAN_ONE 列中的值以及样式数(如果不超过一个,则应在此列中输入 NULL)。我还需要使用 FOR UPDATE 和 WHERE CURRENT OF 作为我的解决方案的一部分。使用基本循环来解决这个问题, 以及任何决策结构的 IF。
这就是我现在所拥有的。 它没有显示任何错误,但不知何故,当我运行此代码时,我的表没有更新/更改。
DECLARE
ata_entId ata_entertainer.entertainer_id%TYPE;
ata_st_entId ata_entertainers_style.entertainer_id%TYPE;
ata_more ata_entertainer.more_than_one%TYPE;
ata_count NUMBER(10) := 0;
CURSOR ata_rec IS
SELECT entertainer_id
FROM ata_entertainers_style
WHERE ata_st_entId = ata_entId
FOR UPDATE;
BEGIN
OPEN ata_rec;
LOOP
FETCH ata_rec INTO ata_st_entId;
EXIT WHEN ata_rec%NOTFOUND;
IF ata_st_entId = ata_entId THEN ata_more := ata_count+1;
UPDATE ata_entertainer SET more_than_one = ata_more
WHERE CURRENT of ata_rec;
END IF;
END LOOP;
CLOSE ata_rec;
END;
/
【问题讨论】:
请贴出数据库表结构ATA_ENTERTAINER
。
@Abra 我刚刚做了!
根据您发布的图表,表ATA_ENTERTAINER
不包含MORE_THAN_ONE
列。如您的问题所述,您是否已将该列成功添加到表格中?
这是学校的练习吗?在“现实”生活中,人们会使用一条更新语句来执行任务。
【参考方案1】:
解决方案可能是这样的:
DECLARE
ata_more ata_entertainer.more_than_one%TYPE;
CURSOR ata_rec IS
SELECT entertainer_id
FROM ata_entertainer
FOR UPDATE;
BEGIN
for aEntertainer in ata_rec LOOP
select count(*)
into ata_more
from ATA_ENTERTAINERS_STYLE
WHERE entertainer_id = aEntertainer.entertainer_id;
IF ata_more > 1 then
UPDATE ata_entertainer SET more_than_one = ata_more
WHERE CURRENT of ata_rec;
END IF;
END LOOP;
END;
实际上,我不知道 WHERE CURRENT OF
是否在 FOR ... IN LOOP
中工作 - 我把这个留给你去发现。
在现实生活中,您将使用一条语句运行此更新:
update ata_entertainer a SET more_than_one =
(select NULLIF(count(*), 1)
FROM ATA_ENTERTAINERS_STYLE b
where a.entertainer_id = b.entertainer_id);
【讨论】:
【参考方案2】:想想你自己会怎么做。你有一个风格代码和艺人 ID 的列表。您需要浏览列表并计算同一个艺人 ID 出现的次数。您必须为列表中的每个不同的艺人 ID 执行此操作。这意味着要多次浏览列表。如果您可以按艺人 ID 对列表进行排序怎么办?然后您只需要浏览该列表一次,因为具有相同艺人 ID 的所有行会一起出现。因此,您的光标应该是...
cursor ATA_REC is
select ENTERTAINER_ID
from ATA_ENTERTAINERS_STYLE
order by ENTERTAINER_ID
for update;
因此,您开始浏览列表中的行。只要当前行的艺人 ID 与上一行的艺人 ID 相同,就可以增加计数。当一个新的艺人 ID 出现时,你开始一个新的计数,对吧?此外,当艺人 ID 更改时,您将获得最后一个艺人 ID 的样式数。如果该计数超过一 (1),您需要更新 ATA_ENTERTAINER
表。
这是我的解决方案。请注意,它可以编译(在 Oracle 11g Express Edition 中),但我没有在样本数据上对其进行测试(太懒了:-)
declare
ATA_ENT_ID ATA_ENTERTAINER.ENTERTAINER_ID%type;
L_ENTERTAINER_ID ATA_ENTERTAINER.ENTERTAINER_ID%type;
L_FIRST boolean;
L_SUM number(3); -- Assume less than one thousand styles for single entertainer.
--
cursor ATA_REC is
select ENTERTAINER_ID
from ATA_ENTERTAINERS_STYLE
order by ENTERTAINER_ID
for update;
begin
L_ENTERTAINER_ID := -1;
L_FIRST := true;
L_SUM := 0;
open ATA_REC;
loop
fetch ATA_REC into ATA_ENT_ID;
exit when ATA_REC%notfound;
if ATA_ENT_ID = L_ENTERTAINER_ID then
L_SUM := L_SUM + 1;
else
if L_FIRST then
L_FIRST := false;
L_SUM := 1;
L_ENTERTAINER_ID := ATA_ENT_ID;
else
if L_SUM > 1 then
update ATA_ENTERTAINER
set MORE_THAN_ONE = L_SUM
where current of ATA_REC;
end if;
end if;
L_SUM := 0;
L_ENTERTAINER_ID := ATA_ENT_ID;
end if;
end loop;
--
-- Make sure we update the last entertainer.
if L_SUM > 1 then
update ATA_ENTERTAINER
set MORE_THAN_ONE = L_SUM
where current of ATA_REC;
end if;
end;
【讨论】:
以上是关于使用显式游标和循环,找不到错误的主要内容,如果未能解决你的问题,请参考以下文章
selenium 找不到元素 (显式等待 和隐式等待的区别)