1

I am writing a PL/SQL stored procedure which will be called from within a .NET application.

My stored procedure must return

  • the count of values in a table of part revisions, based on an input part number,
  • the name of the lowest revision level currently captured in this table for the input part number
  • the name of the revision level for a particular unit in the database associated with this part number and an input unit ID.

    The unit's revision level name is captured within a separate table with no direct relationship to the part revision table.

Relevant data structure:

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)

With that said, what is the most efficient way for me to query these three data elements into a ref cursor for output? I am considering the following option 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;

However, Toad's Explain Plan returns Cost:2 Cardinality: 1, which I suspect is due to me using DUAL in my main query. Comparing that to option 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

Essentially I don't really know how to compare the results from my execution plans, to chose the best design. I have also considered a version of option 1, where instead of joining twice to the Part table, I select the Part_ID into a local variable, and simply query the Part_Revisions table based on that value. However, this is not something I can use the Explain Plan to analyze.

4

2 に答える 2

0

スカラー値を取得しているようです。カーソルを返すのではなく、クリーンな 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;
于 2013-09-20T18:58:55.510 に答える