创建带有 2 个游标、一个参数并从表中给出结果的 PL/SQL 脚本?
Posted
技术标签:
【中文标题】创建带有 2 个游标、一个参数并从表中给出结果的 PL/SQL 脚本?【英文标题】:Create PL/SQL script with 2 cursors, a parameter and give results from a table? 【发布时间】:2014-09-15 21:32:20 【问题描述】:我需要创建一个脚本,从表 A 中放入一个键号(稍后将用作参数),然后将该参数或键号流入查询中,然后将这些结果转储到保存记录或表中后来的操纵等等。因为每次提取有超过 1 行(实际上每个查询结果或每个声明键有 6 行),我决定使用 Bulk Collect 子句。虽然我在不同数据库上的初始测试有效,但我还没有弄清楚为什么真正的脚本不工作。
这是我使用的测试脚本:
DECLARE
--Cursors--
CURSOR prod_id is select distinct(product_id) from product order by 1 asc;
CURSOR cursorValue(p_product_id NUMBER) IS
SELECT h.product_description,o.company_short_name
FROM company o,product h
WHERE o.product_id =h.product_id
AND h.product_id =p_product_id
AND h.product_id IS NOT NULL
ORDER by 2;
--Table to store Cursor data--
TYPE indx IS TABLE OF cursorValue%ROWTYPE
INDEX BY PLS_INTEGER;
indx_tab indx;
---Variable objects---
TotalIDs PLS_INTEGER;
TotalRows PLS_INTEGER := 0 ;
BEGIN
--PARAMETER CURSOR RUNS---
FOR prod_id2 in prod_id LOOP
dbms_output.put_line('Product ID: ' || prod_id2.product_id);
TotalIDs := prod_id%ROWCOUNT;
--FLOW PARAMETER TO SECOND CURSOR--
Open cursorValue(prod_id2.product_id);
Loop
Fetch cursorValue Bulk collect into indx_tab;
---data dump into table---
--dbms_output.put_line('PROD Description: ' || indx_tab.product_description|| ' ' ||'Company Name'|| indx_tab.company_short_name);
TotalRows := TotalRows + cursorValue%ROWCOUNT;
EXIT WHEN cursorValue%NOTFOUND;
End Loop;
CLOSE cursorValue;
End Loop;
dbms_output.put_line('Product ID Total: ' || TotalIDs);
dbms_output.put_line('Description Rows: ' || TotalRows);
END;
Test Script Results:
anonymous block completed
Product ID: 1
Product ID: 2
Product ID: 3
Product ID: 4
Product ID: 5
Product ID Total: 5
Description Rows: 6
更新:将问题标记为“已回答”谢谢。
【问题讨论】:
你问了几个问题,有点,但我已经回答了似乎最紧迫的问题。由于您的测试块有效,您似乎已经知道如何使用批量收集(尽管您似乎已经删除了loop
,也许没有将其注释掉)。我不确定一旦错字被修复,你是否还有其他问题,但如果是这样,你应该问一个单独的问题,显示你的真实块的当前和期望的行为。 dbms_output
应该只真正用于基本调试,因为客户端可能不会显示输出 - 虽然不确定你想对数据做什么。
所以拼写正确(感谢我最初没有看到它)。以下是现在的错误: 错误报告:ORA-06550:第 41 行,第 43 列:PLS-00302:必须声明组件“CLAIM_NUM” ORA-06550:第 41 行,第 11 列:PL/SQL:忽略 SQL 语句06550. 00000 - “行 %s,列 %s:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:
基本上,我希望将第二个游标批量中的行(多个)收集到一个表中,以便案例语句可以引用表中的列。
嗯,第 41 行指的是CUR_CLAIMNUM2.CLAIM_NUM
;但光标正在选择CLAIM_NO
。这是完全一样的错误。抱歉,但这确实是基本调试 - 查看错误,找到代码中的行号,查找错误文本描述的内容...
按照建议,我仔细查看了代码并进行了几处更改(也根据建议),没有任何错误。问题仍然存在,我是否需要声明一条与表的第二个游标具有相同 %ROWTYPE 的记录以显示列? :
【参考方案1】:
第 7 行出现第一个错误。在第 4 行,您有:
CURSOR CUR_CLAIMNUM IS
SELECT DISTINCT(CLAIM_NO)FROM R7_OPENCLAIMS;
... 这似乎是有效的,所以您的列名是CLAIM_NO
。第 7 行:
CURSOR OPEN_CLAIMS (CLAIM_NUM R7_OPENCLAIMS.CLAIM_NUM%TYPE) IS
...所以您将列名输入错误为CLAIM_NUM
,该表中不存在该列名。这是错误消息告诉你的,真的。
其他错误是因为光标无效,因为那个错字。
当你打开第二个游标时你有同名混淆:
OPEN OPEN_CLAIMS (CUR_CLAIMNUM2.CLAIM_NUM);
... 失败,因为游标查询的是CLAIMNO
而不是CLAIMNUM
;除了这里,distinct
进一步混淆了它。您没有为列名起别名,因此 Oracle 应用了一个,您可以参考,但添加您自己的更简单:
CURSOR CUR_CLAIMNUM IS
SELECT DISTINCT(CLAIM_NO) AS CLAIM_NO FROM R7_OPENCLAIMS;
然后
OPEN OPEN_CLAIMS (CUR_CLAIMNUM2.CLAIM_NO);
但我建议您在定义和循环声明中也将光标名称从 CUR_CLAIMNUM
更改为 CUR_CLAIM_NO
。并且拥有名为CUR_CLAIMNUM2
的游标迭代器很奇怪,因为它表明它本身就是一个游标名称;也许像ROW_CLAIM_NO
这样的东西会更清楚。
【讨论】:
以上是关于创建带有 2 个游标、一个参数并从表中给出结果的 PL/SQL 脚本?的主要内容,如果未能解决你的问题,请参考以下文章