pl/sqlのクエリー文テクニックについて個人的にまとめます


1.複数のテーブルが結合してクエリを行う場合、複数のテーブルに必要なキーフィールドを検出するため、複雑な感じがする場合があります.
実はよく分析してみるのは難しくないですね~~~~
a.まず、必要なすべてのフィールドをリストします.

select t.touristid,t.touristname,t.sex,t.mobile,t.times,
       c.cardid,nt.nationname,tp.tourtypename,p.provincename,
       ct.countryid,ct.countryname,h.hotelname,rs.chamberid,
       cc.certificatetypename,bd.days,bd,indate,bd.valid

b.関連するテーブルをリストし、別名を取得する

 from tourist t,touristtype tp,certificate c,certificatetype cc,
        nation nt,province p,country ct,hotel h,rooms rs,
        bookdetail bd,book bk
 
c.すべてのテーブルのフィールドを関連付ける

   where t.tourtypeid=tp.tourtypeid
     and cc.typeid=c.typeid
     and t.countryid=ct.countryid
     and t.nationid=nt.nationid
     and t.certificateid=c.certificateid
     and t.provinceid=p.provinceid
     and t.touristid=bk.touristid
     and bk.hotelid=h.hotelid
     and bk.bookid=bd.bookid
     and bd.roomid=rs.roomid

d.最後に今回のクエリの制約を加えればよい
大功告成~~~~ははは
完全なストアド・プロシージャ・コードは次のとおりです.
--証明書番号、および観光客の名前(氏名曖昧検索)に基づいて、観光客に関するすべての宿泊情報を検索する

procedure searchfulltourinfo(p_cardid certificate.cardid%type,
                             p_touristname tourist.touristname%type,
                             b out ems_cursor)
as
begin
 open b for
 select distinct
        t.touristid,t.touristname,ct.countryid,
        cc.certificatetypename,t.sex,t.mobile,
        t.times,c.cardid,nt.nationname,tp.tourtypename,
        p.provincename,ct.countryname,h.hotelname,
        rs.chamberid,bd.days,bd.indate,bd.valid


   from tourist t,touristtype tp,certificate c,certificatetype cc,
        nation nt,province p,country ct,hotel h,rooms rs,
        bookdetail bd,book bk

   where t.tourtypeid=tp.tourtypeid
     and cc.typeid=c.typeid
     and t.countryid=ct.countryid
     and t.nationid=nt.nationid
     and t.certificateid=c.certificateid
     and t.provinceid=p.provinceid
     and t.touristid=bk.touristid
     and bk.hotelid=h.hotelid
     and bk.bookid=bd.bookid
     and bd.roomid=rs.roomid
     and (p_cardid is null or c.cardid=p_cardid)
     ----              ,          
     and (p_touristname is null or upper(trim(t.touristname)) 
         like'%'||upper(trim(p_touristname))||'%')
     and rownum<=60
     order by bd.indate desc;
end searchfulltourinfo;

2,ファジイクエリ
ファジイクエリの構文は次のとおりです.

select * from tourist t 
     where upper(trim(t.touristname)) 
      like '%'||upper(trim(p_touristname))||'%';

3、サブクエリ(テンポラリ・テーブルと同様)
条件が複雑な場合は、条件クエリーの一部で生成された結果セットを実装してみることができます.
結果セットから最終結果を検出する

--    id     id      
PROCEDURE GETPHOTONUMBER(P_USERID NUMBER,
                         P_TYPE NUMBER,
                         P_RESULT OUT NUMBER)
AS
V_A NUMBER :=-1;
BEGIN
P_RESULT:=-1;
IF P_TYPE=1 THEN--        
      SELECT COUNT(P.PHOTOID) 
     INTO V_A FROM PHOTOES P
     WHERE EXISTS(SELECT 1/*+rule*/ FROM PHOTOES P,HOTEL H
                                           WHERE H.VALID=0
                                             AND P.VALID=0
                                             AND P.HOTELID=H.HOTELID
                                             AND P.PHOTOTYPEID=P_TYPE
                                             AND H.USERID=P_USERID);

ELSe
IF P_TYPE=2 THEN--        
     SELECT COUNT(P.PHOTOID) 
    INTO V_A FROM  PHOTOES P
    WHERE EXISTS(SELECT 1/*+rule*/ FROM PHOTOES P,HOTEL H
                                          WHERE H.VALID=0
                                            AND P.VALID=0
                                            AND P.HOTELID=H.HOTELID
                                            AND P.PHOTOTYPEID=P_TYPE
                                            AND H.USERID=P_USERID);

P_RESULT:=V_A;
else
P_RESULT:=-1;
END IF;
END IF;
END GETPHOTONUMBER;