【发布时间】:2011-08-10 08:36:25
【问题描述】:
CREATE or REPLACE PROCEDURE TEST(
activationStartDate IN DATE,
activationEndDate IN DATE,
deActivationStartDate IN DATE,
deActivationEndDate IN DATE
)
AS
FirstNameListTable LIST_TABLE;
{--COMMENT :LIST_TABLE is nested table :create or replace TYPE "LIST_TABLE" as table of varchar2(20);-----Nested Table Declaration
/
}
totalSameFirstName NUMBER;
j NUMBER := 1;
BEGIN
SELECT first_name BULK COLLECT INTO FirstNameListTable FROM Employee where start_date between activationStartDate AND activationEndDate
MINUS
SELECT first_name FROM Employee where start_date between deActivationStartDate AND deActivationEndDate
FOR i IN FirstNameListTable.FIRST .. FirstNameListTable.LAST LOOP
SELECT count(*) INTO totalSameFirstName FROM Employee where start_date between activationStartDate AND activationEndDate AND first_name=FirstNameListTable(i)
IF totalSameFirstName > 2 THEN
---business logic
END IF;
END LOOP;
其实上面提到的有两个查询
让这个查询作为 Q1:
SELECT first_name BULK COLLECT INTO FirstNameListTable FROM Employee where start_date between activationStartDate AND activationEndDate
MINUS
SELECT first_name FROM Employee where start_date between deActivationStartDate AND deActivationEndDate
此查询为 Q2:
SELECT count(*) INTO totalSameFirstName FROM Employee where start_date between activationStartDate AND activationEndDate AND first_name=FirstNameListTable(i)
在这两个 qyery 中,我都在扫描完整的表,我认为没有必要。我正在迭代 Q1 的结果,然后再次扫描表以计算相似的 first_name。如果一个特定的名字出现两次以上,我会编写业务逻辑。
我可以将这两个查询结合起来吗,意味着我想将 Q1 的结果存储在一些 PL/SQL 数据结构中,并希望对 Q1 的结果执行 Q2。
我想将 Q1 修改为
SELECT * BULK COLLECT INTO FirstNameListTable FROM Employee where start_date between activationStartDate AND activationEndDate
MINUS
SELECT * FROM Employee where start_date between deActivationStartDate AND deActivationEndDate
但是如何在 pl/sql dataStructure 中存储“select *”结果以及如何将这些记录传递给第二个查询。你能告诉我我的代码会是什么样子吗? 尝试更清楚一点,我在这个 PL/SQL 中缺乏想法,即使它听起来像一个经典:我花了几个小时试图玩这个,但无处可去
@奥利 我按照您的建议更改了代码,但出现了一些错误并且无法解决它们
CREATE or REPLACE PROCEDURE TEST(
activationStartDate IN DATE,
activationEndDate IN DATE,
deActivationStartDate IN DATE,
deActivationEndDate IN DATE,
Out_Entity OUT TEST1.RefCsr
)
AS
FirstNameListTable CRITERIA_LIST_TABLE;
out NUMBER;
j NUMBER := 1;
CURSOR main_cur
IS
WITH include_rec
AS (SELECT first_name,COUNT(1) OVER (PARTITION BY first_name) name_count FROM employee where start_date between activationStartDate AND activationEndDate
MINUS
SELECT first_name FROM employee where start_date between deActivationStartDate AND deActivationEndDate)
SELECT first_name FROM include_rec WHERE name_count > 2;
BEGIN
OPEN main_cur;
FETCH main_cur BULK COLLECT INTO FirstNameListTable;
CLOSE main_cur;
OPEN Out_Entity FOR SELECT * FROM TABLE(
CAST (
FirstNameListTable AS LIST_TABLE
)
) Nos;
END;
/
错误 1:PL/SQL:SQL 语句被忽略 {Indicating : "WITH include_rec" Line} 错误 2:PL/SQL:ORA-01789:查询块的结果列数不正确{指示行:“AS (SELECT first_name,COUNT(1) OVER (PARTITION BY first_name)”} 提前致谢 等待你的回复
【问题讨论】:
-
请不要在 SO 上创建迁移问题。 “迁移问题”是一个得到答案的问题,然后被编辑以添加新内容、新问题,然后得到答案,然后被编辑以添加更多内容。它们通常包含诸如“我尝试了您的建议,它确实解决了我的问题,但现在我有一个新问题......”之类的文字。在这种情况下,请在此处接受答案,再解决您的问题,然后在新问题中留下新问题。
-
这种情况的典型结果是,回答的人将不得不继续编辑他们的答案。此外,新人可能只回答最新的问题,而将解决方案的零碎部分留在所有您的问题中。提出 1 个问题,接受 1 个答案,然后继续。