Last updated: 12/22/2002 Top ドキュメントTop

データベース管理システム 管理者用ガイド
基本的な処理の流れと関連するAPI

データの検索

概要

データの流れ

検索条件式を受け取り、検索結果を出力します。 DBIPgSystem::search メソッド によって処理されます。

DBIPgSystem::search メソッド

パラメータ

code_dist ( STRING )
文字コードに判別に利用される文字列。 文字コード のページを参照してください。
srcsid ( STRING )
検索用のセッションのID。
cols ( STRING )
検索をしたいカラム。$dbi->{db}{cols} のキーを指定すると、 対応する値が "テーブルの列名" として SELECT文に利用されます。 デフォルト値は、絞り込み検索または前回と同じ条件での検索ならば、 前回の検索時の $qs->{cols}、さもなくば 'default' です。
where ( STRING )
WHERE句。直接条件式を渡す場合に条件式を指定します。
direct ( BOOLEAN )
フォームから直接条件式を渡す場合で、 絞り込み検索でない場合は true にします。
and ( BOOLEAN )
絞り込み検索を行う場合は true にします。
v_where ( STRING )
間接的に条件式を渡す場合に条件式を指定します。
:* ( STRING )
名前が ':' で始まるパラメータです('*' は任意の文字列です)。 間接的に条件式を渡す場合に利用します。
join ( STRING )
JOIN句。$dbi->{db}{sql_join} のキーを指定すると、 対応する値が JOIN句として使われます。
page ||= 1 ( NUM )
ページ番号。検索結果は、($qs->{page} - 1 ) * $qs->{searchnum} + 1 件目から $qs->{searchnum} 件分出力されることになっています。
searchnum ||= $dbi->{global}{searchnum_default} ( NUM )
検索結果の表示件数。
html ( STRING )
テンプレート。$dbi->{template}{search} のキーを指定します。
strict ( BOOLEAN )
右辺値にフィルタを通さず、検索用カラムも使わない場合は true にします。URIから直接 WHERE句を指定した場合は、 必ず true とみなされます。
usemeta ( BOOLEAN )
条件式中のメタ文字をメタ文字として扱う場合は true にします。 条件式に記述した文字そのものを検索したい場合は false にします。 間接的に条件式を渡す場合のみ、この値が使われます。
order ||= 'system_state DESC, system_did, system_rid' ( STRING )
ORDER句。指定された値が(チェックの後)そのまま ORDER句として使われます。 セッションの情報を使う場合は、 デフォルト値はセッションの対応する値になります。

出力

list ( ARRAYREF )
DBI::selectall_arrayref の返り値。検索結果。
page ( NUM )
ページ番号。検索に成功すれば $qs->{page}、さもなければ 1。
total ( NUM )
検索されたデータの総数。
numpage ( NUM )
総ページ数。ただし検索に失敗すれば 1。
searchnum = $qs->{searchnum} ( NUM )
where ( STRING )
入力された WHERE句。絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値を出力します。 直接 WHERE句を指定した場合は $qs->{where}、 間接的に WHERE句を指定した場合は undef を出力します。
strict ( BOOLEAN )
$qs->{strict} に対応する値。絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値を出力します。 URIから直接 WHERE句を指定した場合は 1、それ以外では、$qs->{strict} を出力します。
join ( STRING )
$qs->{join} に対応する値。絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値を出力します。 さもなければ、$qs->{join} を出力します。
sql_from ( STRING )
検索に用いたSELECT文の "FROM" に続く文字列(主テーブルの名前と、 $qs->{join} に値があればその値)を出力します。
sql_where ( STRING )
検索に用いたSELECT文のWHERE句。 前回と同じ条件での検索のときは前回の sql_where の値、 WHERE句が解析できたときは解析後のWHERE句、 さもなければ空文字列を出力します。
v_qs ( HASHREF )
$qs->{":*"} に対応する値。絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値を出力します。 さもなければ、$qs->{":*"} に対応する名前と値を出力します。 例えば $qs->{":query1"} が与えられた場合、 $var{v_qs}{query1} に値が格納されています。
html ( STRING )
$qs->{html} に対応する値。 $qs->{html} が空の場合は前回の $qs->{html} の値、 セッションIDの指定がなければ文字列 'default' を出力します。
usemeta ( BOOLEAN )
$qs->{usemeta} に対応する値。 絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値を出力します。 さもなければ、$qs->{usemeta} を出力します。
srcsid ( STRING )
検索用のセッションのID。前回と同じ条件での検索の場合は $qs->{srcsid}、さもなければ新しく作られたセッションのIDを出力します。
cols ( STRING )
$qs->{cols} に対応する値。$qs->{cols} に値があればその値、 値がなく絞り込み検索や前回と同じ条件での検索の場合は、 前回の検索時と同じ値、さもなければ文字列 'default' を出力します。
uri_qs ( STRING )
URIクエリー。データが 1 件以上検索されたときに出力します。 この値をURIクエリーとして使うと、同じ条件で検索が行えます。
order ( STRING )
$qs->{order} に対応する値。

補足説明

DBIPgSystem::search メソッド を参照してください。

検索条件式を指定する方法は、以下に示します。

1. より柔軟なフォームから間接的に条件式を与える方法 (A)
$qs->{v_where} に値がある場合はこの方法だとみなされます。 管理者により用意されたフォームを使って WHERE句を意識せずに 条件を指定することができます。 必要に応じて $qs->{":*"} に値がある必要があります。 また、$qs->{join}, $qs->{strict}, $qs->{usemeta} を併用することができます。
2. フォームから条件式を直接与える方法 (A)
1. 以外の場合で $qs->{direct} が true の場合はこの方法だとみなします。 WHERE句を直接指定して検索を行えます。 一般に、間接的に条件式を指定する方法よりも細かな検索が行えます。 $qs->{where} に値がある必要があります。 また、$qs->{join}, $qs->{strict} を併用することができます。
3. URIクエリーから条件式を直接与える方法 (B)
1,2. 以外の場合で $qs->{srcsid} に値がない場合は、この方法だとみなします。 URIクエリーから直接WHERE句を指定して、検索を行うことができます。 フォームから条件式を直接与える方法とほとんど同様の処理が行われます。 $qs->{where} に値がある必要があります。 また、$qs->{join}, $qs->{strict} を併用することができます。
4. 絞り込み検索のために条件式を直接与える方法 (C)
1,2,3. 以外の場合で $qs->{and} が true の場合は、 この方法だとみなされます。 前回の検索条件にさらに条件を加え、絞り込み検索を行うことができます。 条件式は、WHERE句を直接指定する形で指定します。 絞り込むための条件式が解析された後で、前回の検索条件と AND で 結合されます。 $qs->{srcsid} に値があり、$qs->{where} に絞り込み検索のための条件式が 格納されていなければいけません。 また、$qs->{strict} を併用することができます。
5. 前回と同じ条件式を与える方法 (C)
1,2,3,4. 以外の場合は、この方法だとみなします。 検索結果のページを変えるときなどに、この方法が効果的です。 $qs->{srcsid} に値がある必要があります。

$qs->{cols}, $qs->{page}, $qs->{searchnum}, $qs->{html_next} は、上のどの方法でも指定することができます。

v_where と :* の使い方

より柔軟なフォームから間接的に条件式を与える方法では、 $qs->{v_where} と $qs->{":*"} を使います。 $qs->{v_where} の中にある "#{*}" という文字列が $qs->{":*"} に置換され、 最終的な $qs->{v_where} の値が WHERE句としてその後解析されます ('*' は任意の文字列です)。 ただし、対応するパラメータがない場合は置換されません、

次に、使用例を示します。

<form method="post" action="nph-search.cgi"> <input type="text" name=":v1" value="<% print $var{v_qs}{v1} %>"> <input type="text" name=":v2" value="<% print $var{v_qs}{v2} %>"> <input type="hidden" name="v_where" value="col1 = '#{v1}' AND col2 = '#{v2}"> <input type="submit" value="検索">
v_where, :* の使用例

上の例では、パラメータ ":v1", ":v2", ":v_where" が フォームから送信されます。 $qs->{":v1"}, $qs->{":v2"} は、それぞれ $qs->{v_where} の "#{v1}", "#{v2}" と書かれた位置に挿入されます。 (特に理由がない限り、 上の例のように適切にシングルクォートしてください。) この処理は、WHERE句の構文とは無関係に行われますので、 $qs->{v_where} の任意の部分を $qs->{":*"} への参照に変えることができます。 上の例では、col1, =, AND, col2, = の部分を $qs->{":*"} に置き換えることが できますし、"col1 = #{v1}" の部分を一つの $qs->{":*"} に置き換えることも できます。

WHERE句の解析方法

WHERE句の解析は、DBIPgSystem::_make_cond_sentence メソッド によって行われます。

ここでは、"カラム名 演算子 値" の形をした、 boolean型を返す一番小さな構成要素を単式と呼ぶことにします。 また、各単式の、演算子より前の文字列を左辺値、 演算子より後の文字列を右辺値と呼びます。

WHERE句は、単式が "AND", "OR" で結合された形でなければいけません。 SpotgreSQL の規則と同様に "AND" のほうが "OR" よりも優先順位が高く、 丸括弧 "(", ")" を使って結合の強さを変えることができます。

基本的には、左辺値は PostgreSQL の識別子、右辺値は PostgreSQL の定数と 同様の記述である必要があります。 ただし、左辺値や右辺値に、引用符, AND, OR, ( ) の文字列そのものを 含まない場合は、二重引用符や単一引用符で囲む必要はありません。 逆にこれらの文字列を左辺値に含めたいときは左辺値を二重引用符 "" で囲み、 右辺値に含めたいときは右辺値を単一引用符で囲みます。 引用符で囲まれた引用符の解釈は、PostgreSQL と同じはずです。

単式の中では次の演算子が使えます: ~, ~*, !~, !~*, =, <=, >=, <, >, LIKE, NOT LIKE, IS NULL, IS NOT NULL。 これらの演算子の意味は PostgreSQL と同じです。 また、本システム独自の演算子として、~, ~*, !~, !~* の後ろに "^", "$", "^$" を付けた演算子 ― ~^, ~$, ~^$, ~*^, ~*$, ~*^$, ... ― をサポートしています。 "^" を付けると、文字列の先頭とのマッチングが行われ、 "$" を付けると、文字列の末尾とのマッチングが行われます。 "^$" を付けると、文字列全体とのマッチングが行われます。 (ただし、複数の値を格納できるカラムでは、 それぞれ、区切り文字で始まる文字列、区切り文字で終わる文字列、 区切り文字で始まり区切り文字で終わる文字列とのマッチングが行われます。)

検索時の条件に応じて、左辺値がどのカラム名を表しているかを調べられます。 左辺値は、$dbi->{dbcol}{$dbt}[*]{name} の値か、 対応する検索用カラムの名前か、 またはシステム定義カラムの名前でなければいけません。 ただし、フォームからWHERE句を直接指定した場合や、 絞り込み検索の場合は、$dbi->{dbcol}{$dbt}[*]{print} の値や、 $dbi->{db}{alias} の値を左辺値として使えます。

右辺値は、比較的細かく解析されます。概略を後で示します。

右辺値の処理

ここでは、右辺値について行われる大まかな処理の流れを、 具体例と共に示します。

(1)(2)(3) (4)(5)(6)
I.'''*\n' ''*\n '*\n '\'*\n'
II.''*\n '\'\'*\\n' \'\'*\\n ''*\n '*\n '\'*\n'
III.''*\n '\'\'*\\n' \'\'*\\n ''*\n '\'\'*\\n'
IV.''*\n '\'\'*\\n' \'\'*\\n ''*\n ''\*\\n '\'\'\\*\\\\n'
  1. WHERE句を間接的に与えられた場合は、フォームの中の文字列を DBIPgSystem::pgsqlunpack 関数 を使ってエスケープします。 次に、$qs->{v_where} の中に値が埋め込まれます。 実際には、この処理は DBIPgSystem::search メソッド が行います。
  2. 条件式を単式に分解し、さらに各単式を左辺値、演算子、右辺値に分解します。 次に、右辺値が正しくクォートされていることを確認します。 また、文字列の先頭と末尾にシングルクォートがあれば、取り除きます。
  3. WHERE句を間接的に与えられた場合は、 DBIPgSystem::pgsqlpack 関数 を使ってアンエスケープします。
  4. usemeta が true の場合は、 DBIPgSystem::pgsqlpack 関数 を使ってアンエスケープします。
  5. この時点で、右辺値は、表現したい文字列そのものになっているはずです。 そこで、オプションに応じて、右辺値を subst に通したり、 検索用カラム生成のためのフィルタを通します。 strict が true の場合や、 usemeta が true で文字列中にメタ文字が含まれる場合などは、 この処理を行いません。 その後、usemeta が false ならば、 LIKE や ~ で特別に扱われる文字をエスケープします。
  6. 最後に、DBIPgSystem::pgsqlunpack 関数 を使ってエスケープし、 両端にシングルクォートを付けます。

具体例は、それぞれ、次の場合を示しています。

I ― WHERE句を直接与えた場合, usemeta: true
II ― WHERE句を間接的に与えた場合, usemeta: true
III ― WHERE句を間接的に与えた場合, usemeta: false, 演算子: ~,LIKE 以外
IV ― WHERE句を間接的に与えた場合, usemeta: false, 演算子: ~,LIKE