[s2container-php5:108] Re: IN 句に配列を利用してセットした時、「ORA-01008: バインドされていない変数があります。」

Yusuke Hata [E-MAIL ADDRESS DELETED]
2007年 9月 24日 (月) 23:21:27 JST


ハタです。

詳細な解析ありがとうございます。

> IN 句に配列を利用してセットした時、「ORA-01008: バインドされていない変数があります。」
>
> <snip>
>
>     S2Dao_ParenBindVariableNode.class.php:69 行目
> で、引数のタイプを判定していますが、get_classは、Object以外に対して
> 行うと、 [false] が返却されるようです。
> ※ $hogeIds の要素は、primitive型。
>

たしかに、get_classはfalseを返すので、件のarray(ArrayObjectなどではない)場合は
思ったとおりの動きをしない可能性があります。

その場合は、「その1」にで示されているコードに修正するのがいいのかな。と思います。(get_classに対応するための対処法ならば)

> その1:
>   S2Dao_ParenBindVariableNode.class.php
>      69:      $clazz = get_class($o);
>>      69:      if(($clazz = get_class($o)) === false){
>      ++:          $clazz = gettype($o);
>      ++:      }
>

私が当初予定していたbindArgsに対応するクラスはS2Dao_ArrayListを使用するタイプだったのですが
それでも件には適用できなさそうですね…

ということで(?)、「その1」の方法でsvnリポジトリを更新しておきました。
(「その2」のBasicHandler側で対処するのは、少なくとも1.1.2では影響範囲が大きそうなので検討します)

もしお急ぎであれば最新をリポジトリから取得してください。
svn export https://www.seasar.org/svn/s2dao.php5/branches/S2Dao.PHP5-1.1.2/ S2Dao.PHP5

以上、よろしくお願いします。

Noriyuki ITAGAKI <[E-MAIL ADDRESS DELETED]> wrote:

> はじめまして、板垣と申します。
> 
> 
> 以下の環境で利用させていただいております。
> 
> ・s2dao.php5-1.1.2.tar.gz
> ・s2container.php5-1.1.3.zip
> ・Oracle10g
> ・Apache/2.0.59 (Win32) PHP/5.2.3
> ・WindowsXP Pro
> 
> 
> 表題の件ですが、IN句の値に配列で設定したいのですが、以下のようにして、
> 呼び出したときエラーが発生しました。設定の方法は正しいでしょうか。
> 
> ○PHPコード
> $hogeIds= array(1,2,3);
> $dao->getHogeList($hogeIds);
> 
> ○*****_getHogeList.sql
> select * form hoge_table where hoge_id in /*hogeIds*/(1)
> 
> ○エラー
>   OCIStmtExecute: ORA-01008: バインドされていない変数があります。
>       (ext\pdo_oci\oci_statement.c:142)
>        in S2Dao\s2dao.core.classes.php on line 538
> 
> --
> 
> ソースコードを読んだところ、
>     S2Dao_ParenBindVariableNode.class.php:69 行目
> で、引数のタイプを判定していますが、get_classは、Object以外に対して
> 行うと、 [false] が返却されるようです。
> ※ $hogeIds の要素は、primitive型。
> 
>   68:    if($o !== null){
>   69:      $clazz = get_class($o);
>   70:    }
>   71:  }
>   72:  $ctx->addSql('(');
>   73:  $ctx->addSql('?', $array[0], $clazz);
> 
> そのため、属性(クラス)が false であるのに対して、
>   s2dao.core.classes.phpの368行目
> で以下のようにして判定しているため、最終的に372 行目が実行され、
>   $this->getBindParamTypes($argType)
> がUnknownタイプのため、「ORA-01008」エラーになるようです。
> 
>  368:  if($argType !== null){
>  369:    if($this->isNullType($arg, $argType)){
>  370:      $ps->bindValue($i + 1, $arg, S2Dao_PDOType::Null);
>  371:    } else {
>  372:      $ps->bindValue($i + 1, $arg,
>                           $this->getBindParamTypes($argType));
>  373:    }
>  374:  } else {
>  375:    $ps->bindValue($i + 1, $arg,
>                          $this->getBindParamTypes($phpType));
>  376:  }
> 
> 
> 
> 以下のような修正方法があると思いますが、どのような対応が適切でしょう
> か?または、そもそも、設定の方法が間違っていますでしょうか。
> ※ 現在は、「その2」の対応でテストを行っております。
> 
> その1:
>   S2Dao_ParenBindVariableNode.class.php
>      69:      $clazz = get_class($o);
>>      69:      if(($clazz = get_class($o)) === false){
>      ++:          $clazz = gettype($o);
>      ++:      }
> 
> その2:
>   s2dao.core.classes.php(368)
>     368:  if($argType !== null){
>>     368:  if($argType !== null && $argType !== false){
> 
> 
> または、IN句に設定する配列を作成するときに、'String'、'Integer'
> という名前のクラスを作成し、
>      $hogeIds= array(new Integer(1), new Integer(2), new Integer(3));
> として、get_class の戻り値が返却されるように設定するのでしょうか。
> 
> 
> 同じような経験のある方がいらっしゃいましたら、ご教示ください。
> 
> 以上、よろしくお願いいたします。
> 

-- 
Yusuke Hata <[E-MAIL ADDRESS DELETED]>
blog: http://blog.xole.net/


S2Container-PHP5 メーリングリストの案内