kuniku’s diary

はてなダイアリーから移行(旧 d.hatena.ne.jp/kuniku/)、表示がおかしな箇所はコメントをお願いします。記載されている内容は日付およびバージョンに注意してください。直近1年以上前は古い情報の可能性が高くなります。

S2DaoにおけるIFコメント、BEGINコメントの挙動

s2daoの「AND」文字列を消すタイミングというか消す条件がわからない。
なんとなくわかった。(2009-02-02の追記参照)

SELECT 
・・・
  TABLE3 T3
WHERE
・・・
  /*BEGIN*/----行(1)
    /*IF dto.xxx1=="1"*/
      T3.XXX='1'
    /*END*/
    
    /*IF dto.xxx1=="1"*/
      or T3.XXX='2'
    /*END*/

      not exists (
        select
          *
        from
          VIEW1  V1
          inner join VIEW2  V2
            on V1.XX_SEQ = V2.XX_SEQ
        where
          V1.XX_CD ='9999'
          AND
          V1.XX_SEQ = T3.XX_SEQ
          /*BEGIN*/----行A
            AND
            /*IF dto.xxCode !=null*/ 
             AND V1.XXNO = /*dto.xxCode*/'10000'
            /*END*/
      
            /*IF dto.xxDate1 != '' || dto.xxDate2 != ''*/
              AND to_char(V2.HOGE_DATE,'YYYY/MM/DD')
              /*IF dto.xxDate1 != '' && dto.xxDate2 != ''  */between /*dto.xxDate1*/'1999/01/01' and /*dto.xxDate2*/'2009/01/30'
                -- ELSE
                  /*IF dto.xxDate1 == '' && dto.xxDate2 !=''  */
                    <=/*dto.xxDate2*/'2009/01/30'
                  /*END*/
                  /*IF dto.xxDate1 != '' && dto.xxDate2 ==''  */
                    >=/*dto.xxDate1*/'1999/01/0'
                  /*END*/
      
              /*END*/
            /*END*/
          /*END*/----行B
      )
  /*END*/----行(2)

上記だと、問題なく実行できるけど

行A、行Bの

/*BEGIN*/

/*END*/

を付与しないで、以下のように記述すると

(略)
  where
    V1.XX_CD ='9999'
    AND
    V1.XX_SEQ = T3.XX_SEQ
      /*IF dto.xxCode !=null*/
        AND V1.XXNO = /*dto.xxCode*/'10000' ----行C
      /*END*/

      /*IF dto.xxDate1 != '' || dto.xxDate2 != ''*/
        AND to_char(V2.HOGE_DATE,'YYYY/MM/DD') ----行D
        /*IF dto.xxDate1 != '' && dto.xxDate2 != ''  */between /*dto.xxDate1*/'1999/01/01' and /*dto.xxDate2*/'2009/01/30'
          -- ELSE
            /*IF dto.xxDate1 == '' && dto.xxDate2 !=''  */
              <=/*dto.xxDate2*/'2009/01/30'
            /*END*/
            /*IF dto.xxDate1 != '' && dto.xxDate2 ==''  */
              >=/*dto.xxDate1*/'1999/01/0'
            /*END*/

        /*END*/
      /*END*/
)

行Cの最初の「AND」もしくは、行Dの最初の「AND」が削除されてしまう


/*IF〜*/  /*END*/ がひとつ1もtrueを返さない場合は、ANDを削除している模様。

(略)
  where
  /*IF "A"=="A"*/
    V1.XX_CD ='9999'
  /*END*
    AND
    V1.XX_SEQ = T3.XX_SEQ
      /*IF dto.xxCode !=null*/
        AND V1.XXNO = /*dto.xxCode*/'10000'  ----行C
      /*END*/

      /*IF dto.xxDate1 != '' || dto.xxDate2 != ''*/
        AND to_char(V2.HOGE_DATE,'YYYY/MM/DD')  ----行D
        /*IF dto.xxDate1 != '' && dto.xxDate2 != ''  */between /*dto.xxDate1*/'1999/01/01' and /*dto.xxDate2*/'2009/01/30'
          -- ELSE
            /*IF dto.xxDate1 == '' && dto.xxDate2 !=''  */
              <=/*dto.xxDate2*/'2009/01/30'
            /*END*/
            /*IF dto.xxDate1 != '' && dto.xxDate2 ==''  */
              >=/*dto.xxDate1*/'1999/01/0'
            /*END*/

        /*END*/
      /*END*/

と記述すると、行C、Dともに ANDが付与されたままのSQLで実行できる。

どう回避すべきなんだろ。 /*IF "A"=="A"*/〜/*END*/で 回避するのがわかりやすいのか・・・


2009-01-31 AM1:50追記
行(1)の /*BEGIN*/ 〜 /*END*/
で 不要な OR が存在する場合(WHERE or A=1のように、orが入りSQL
成立しなくなるの)を回避する際のときの動作の影響を受けるみたいだ。
ネストしすぎてるから、判断できないのか。。。

2009-02-02 12:50追記

ちょっと再考してみた。

BEGIN〜END と ELSE
コメントの勘違いから始まった。

/*BEGIN*/
    [あああ(ANDとかもあり)]
    SQL文1
    
    /*IF 条件2  */ SQL文2 /*END*/
    
    /*IF 条件3  */ SQL文3 /*END*/

/*END*/

とあるとき、条件2、条件3ともにみたさない(trueでない)ときに
[あああ]、SQL文1、SQL文2、SQL文3 すべて解釈されなくなる。

BEGIN〜ENDは、
ELSE コメントを含まない複数の条件コメントにおいて
すべての条件をみたさない場合に
BEGIN〜ENDの中にあるSQLを解釈しないようにする機能

別の表現だと
WHERE句とか関係なく、BEGIN〜END内にあるものがSQLを解釈するか
しないかの対象となり、IFが1つでも成立していればBEGIN〜END内は
解釈される。


よって、ELSEがあるのに関わらず ELSEでSQL文が出力されない
のがよくない。

ELSEは、IF〜ENDがみたさない場合に、
必ずELSE内のSQLがみたされるようにしておくべきなんだろう

で、SQLがよくない。というか書き方がよくない

to_charを複数回記述したくない&&Betweenで見た目をわかりやすく
と思って、ELSEを入れたけど

		
where
    V1.XX_CD ='9999'
    AND
    V1.XX_SEQ = T3.XX_SEQ
    /*BEGIN*/----行A
       AND
      /*IF dto.xxCode !=null*/ 
          AND V1.XXNO = /*dto.xxCode*/'10000'
      /*END*/

            /*IF dto.xxDate1 == '' && dto.xxDate2 !=''  */
            AND to_char(V2.HOGE_DATE,'YYYY/MM/DD') <=/*dto.xxDate2*/'2009/01/30'
            /*END*/
            /*IF dto.xxDate1 != '' && dto.xxDate2 ==''  */
            AND to_char(V2.HOGE_DATE,'YYYY/MM/DD') >=/*dto.xxDate1*/'1999/01/0'
            /*END*/
		  
      /*END*/
    /*END*/----行B

となるように、すべきか。
なので、行A、BのBEGIN〜END は、あってよい。行Aの後のANDも必要ってこと。
ELSEがあるのに、ELSE内でSQLが置き換わらない(出力されない、SQLが成立していない)ような
書き方をしたことが間違いだった。