Stored procedures PLSQL存储过程的最有效版本
我正在编写一个PL/SQL存储过程,它将从.NET应用程序中调用 我的存储过程必须返回Stored procedures PLSQL存储过程的最有效版本,stored-procedures,plsql,sql-execution-plan,Stored Procedures,Plsql,Sql Execution Plan,我正在编写一个PL/SQL存储过程,它将从.NET应用程序中调用 我的存储过程必须返回 基于输入零件号的零件修订表中的值计数 此表中当前为输入零件号捕获的最低修订级别的名称 与此零件号和输入装置ID关联的数据库中特定装置的修订级别名称 装置的修订级别名称被捕获在单独的表中,与零件修订表没有直接关系 相关数据结构: Table Part has columns: Part_ID int PK Part_Number varchar2(30) Table Part_Revisi
- 基于输入零件号的零件修订表中的值计数
- 此表中当前为输入零件号捕获的最低修订级别的名称
- 与此零件号和输入装置ID关联的数据库中特定装置的修订级别名称 装置的修订级别名称被捕获在单独的表中,与零件修订表没有直接关系
Table Part has columns:
Part_ID int PK
Part_Number varchar2(30)
Table Part_Revisions:
Revision_ID int PK
Revision_Name varchar2(100)
Revision_Level int
Part_ID int FK
Table Unit:
Unit_ID int PK
Part_ID int FK
Table Unit_Revision:
Unit_ID int PK
Revision_Name varchar2(100)
话虽如此,对我来说,将这三个数据元素查询到ref游标以进行输出的最有效的方法是什么?我正在考虑以下备选方案1:
OPEN cursor o_Return_Cursor FOR
SELECT (SELECT COUNT (*)
FROM Part_Revisions pr
inner join PART pa on pa.part_id = pr.part_id
WHERE PA.PART_NO = :1 )
AS "Cnt_PN_Revisions",
(select pr1.Revision_Name from Part_Revisions pr1
inner join PART pa1 on pa1.part_id = pr1.part_id
WHERE PA.PART_NO = :1 and pr1.Revision_Level = 0)
AS "Input_Revison_Level",
(select ur.Revision_Name from Unit_Revision ur
WHERE ur.Unit_ID = :2) as "Unit_Revision"
FROM DUAL;
然而,Toad的Explain计划返回Cost:2基数:1,我怀疑这是因为我在主查询中使用了DUAL。将其与备选方案2进行比较:
select pr.Revision_Name, (select count(*)
from Part_Revisions pr1
where pr1.part_id = pr.part_id) as "Count",
(select ur.Revision_Name
from Unit_Revision ur
where ur.Unit_ID = :2) as "Unit_Revision"
from Part_Revisions pr
inner join PART pa on pa.part_id = pr.part_id
WHERE PA.PART_NO = :1 and pr.Revision_Level = 0
本质上,我真的不知道如何比较执行计划的结果,以选择最佳设计。我还考虑了选项1的一个版本,在该版本中,我没有两次连接到Part表,而是将Part_ID选择到一个局部变量中,然后根据该值简单地查询Part_Revisions表。但是,我无法使用解释计划来分析这一点。看起来您正在获得标量值。只需使用干净的sql语句返回值,而不是返回游标。我在.net上做过很多次,效果很好
Procedure get_part_info(p_partnum in part.part_number%type
, ret_count out integer
, ret_revision_level out part_revisions.revision_level%type
, ret_revision_name out part_revisions.revision_name%type) as
begin
select count(*) into ret_count from ....;
select min(revision_level) into ret_revision_level from ...;
select revision_name in ret_revision_name...;
return;
end;
看起来您正在获取标量值。只需使用干净的sql语句返回值,而不是返回游标。我在.net上做过很多次,效果很好
Procedure get_part_info(p_partnum in part.part_number%type
, ret_count out integer
, ret_revision_level out part_revisions.revision_level%type
, ret_revision_name out part_revisions.revision_name%type) as
begin
select count(*) into ret_count from ....;
select min(revision_level) into ret_revision_level from ...;
select revision_name in ret_revision_name...;
return;
end;
您的描述和select语句看起来不同。。。我以SQL语句为基础完成了这个过程
PROCEDURE the_proc
(
part_no_in IN NUMBER
, revision_level_in IN NUMBER
, unit_id_in IN NUMBER
, part_rev_count_out OUT NUMBER
, part_rev_name_out OUT VARCHAR2
, unit_rev_name_out OUT VARCHAR2
)
AS
BEGIN
SELECT COUNT(*)
INTO part_rev_count_out
FROM part pa
WHERE pa.part_no = part_no_in
AND EXISTS
(
SELECT 1
FROM part_revisions pr
WHERE pa.part_id = pr.part_id
);
SELECT pr1.revision_name
INTO part_rev_name_out
FROM part_revisions pr1
WHERE pr1.revision_level = revision_level_in
AND EXISTS
(
SELECT 1
FROM part pa1
WHERE pa1.part_id = pr1.part_id
AND pa.part_no = part_no_in
);
SELECT ur.revision_name
INTO unit_rev_name_out
FROM unit_revision ur
WHERE ur.unit_id = unit_id_in;
END the_proc;
您的描述和select语句看起来不同。。。我以SQL语句为基础完成了这个过程
PROCEDURE the_proc
(
part_no_in IN NUMBER
, revision_level_in IN NUMBER
, unit_id_in IN NUMBER
, part_rev_count_out OUT NUMBER
, part_rev_name_out OUT VARCHAR2
, unit_rev_name_out OUT VARCHAR2
)
AS
BEGIN
SELECT COUNT(*)
INTO part_rev_count_out
FROM part pa
WHERE pa.part_no = part_no_in
AND EXISTS
(
SELECT 1
FROM part_revisions pr
WHERE pa.part_id = pr.part_id
);
SELECT pr1.revision_name
INTO part_rev_name_out
FROM part_revisions pr1
WHERE pr1.revision_level = revision_level_in
AND EXISTS
(
SELECT 1
FROM part pa1
WHERE pa1.part_id = pr1.part_id
AND pa.part_no = part_no_in
);
SELECT ur.revision_name
INTO unit_rev_name_out
FROM unit_revision ur
WHERE ur.unit_id = unit_id_in;
END the_proc;