4D v16.3

QUERY BY ATTRIBUTE

ホーム

 
4D v16.3
QUERY BY ATTRIBUTE

QUERY BY ATTRIBUTE 


 

QUERY BY ATTRIBUTE ( {aTable}{;}{conjOp ;} objectField ; attributePath ; queryOp ; value {; *} ) 
引数   説明
aTable  テーブル in セレクションまたはレコードを返すテーブル 省略時:デフォルトテーブル
conjOp  演算子 in 複数のクエリ(あれば)を連結する際に使用する結合演算子
objectField  フィールド in 属性をクエリするオブジェクトフィールド
attributePath  文字 in 属性の名前またはパス
queryOp  演算子, 文字 in クエリ演算子(比較演算子)
value  テキスト, Number, 日付, 時間 in 比較する値
演算子 in クエリ継続フラグ

説明   

QUERY BY ATTRIBUTEobjectFieldattributePathqueryOp そして value 引数を使用して定義されたクエリ文字列に合致するレコードを検索し、aTable に対しレコードのセレクションを返します。

注: オブジェクトフィールド(4D v15より新たに導入)についての詳細な情報に関しては、オブジェクトフィールドデータ型 のセクションを参照して下さい。

QUERY BY ATTRIBUTE はカレントプロセスにおいてaTable で指定されたテーブルのカレントセレクションを変更し、新しいセレクションの第一レコードをカレントレコードとします。aTable 引数が省略されていた場合、コマンドはデフォルトのテーブルへと適用されます。デフォルトテーブルが設定されていない場合、エラーが発生します。

任意のconjOp 引数を使用すると、QUERY BY ATTRIBUTE の呼び出しを複数のクエリ定義と組み合わせることができます。使用可能な接続演算子はQUERY コマンドに対して使用できるものと同じです:

接続子QUERY BY ATTRIBUTEで使用する記号
AND&
OR|
Except#

conjOp 引数は、複数のクエリの最初のQUERY BY ATTRIBUTE の呼び出しには使用しません。また単一のクエリの場合にも使用しません。複数のクエリにおいて省略された場合、AND (&) 演算子がデフォルトで使用されます。

objectField 引数には、クエリしたい属性のオブジェクトフィールドを渡します。そのオブジェクトフィールドがaTable 引数で指定したテーブルに自動または手動でリレートした1テーブルに属していた場合、objectField には他のテーブルに属するフィールドを指定することもできます。
QUERY BY ATTRIBUTE はドキュメントがオブジェクトフィールドに保存されていた場合、4D Write Proのカスタム属性をサポートします。この点についてのより詳細な情報については、4D Write Proドキュメントを4Dオブジェクトフィールドに保存する の章を参照して下さい。

attributePath 引数にはレコード毎に値を比較したい属性のパスを渡します (例: "children.girls.age")。単一の属性名 (例えば "place") を渡した場合には、オブジェクトフィールドの第一レベルでその名称に合致する属性を指定したことになります。属性"x"が配列であった場合、QUERY BY ATTRIBUTE コマンドは、少なくとも一つの要素が条件に合致する属性"x"を含むレコードを検索します。配列内の属性を検索するためには、attributePath 引数内において属性”x”の名前に".[]"を付与することにより、QUERY BY ATTRIBUTE コマンドに対し、属性"x"が配列であるという事を指示する必要があります(例3を参照して下さい)。

注:

  • 属性名は大文字と小文字が区別されるという点に注して下さい。つまり同じレコード内にて"MyAtt" と "myAtt" という、異なる属性名を持つことができるということです。
  • 属性名は不要な空白を取り除くために短縮されます。例えば、" my first attribute .my second attribute " は、 "my first attribute.my second attribute"として解釈されます。

queryOp 引数は、objectField 引数と value 引数の間に適用される比較演算子です。以下の記号のどれか一つを渡す事ができます:

比較QUERY BY ATTRIBUTEで使用する記号
同値である=
同値でない#
未満<
を超える>
以下<=
以上>=

注: 比較演算子を記号ではなく、テキスト表現で指定することも可能です。詳細な情報に関しては、QUERY コマンドの説明を参照して下さい。

value 引数は、attributePath 引数と比較するためのデータです。この値はattributePath引数と同じデータ型として評価されるものであればどんな表現も可能です。値は一度だけ、クエリの最初に評価されます。値はそれぞれのレコードに対して毎回評価されることはありません。文字列内に含まれる文字列をクエリする("を含む"クエリ)ためには、ワイルドカード記号(@)をvalue 引数に使用して検索したい文字列を隔離します(例:"@Smith@")。この場合、インデックスの利点を一部しか享受しないという点に注して下さい(データ保存のコンパクト化)。

属性によるクエリのストラクチャーは以下の様になります:

 QUERY BY ATTRIBUTE([Table] ;[Table]ObjectField ;"attribute1.attribute2";=;value)

: 全ての演算子(ただし"#"は除く)に対して、オブジェクトフィールドには属性が含まれている、というのが暗示的な前提条件になります。しかしながら、"#"演算子に対しては、未定義の属性も使用可能です(以下を参照して下さい)。

 

"#"演算子を使用した属性のクエリは、そのオブジェクトフィールドに対してプロパティがチェックされているかどうかで結果が異なってきます:

  • ヌル値を空の値にマッププロパティがチェックされている(デフォルトのオプション、多くの場合において推奨)
    この場合、"#"演算子はフィールド内にて検索した値がどの属性にも存在しないレコードを検索します。このコンテキストにおいては、4Dは以下の場合においても同じように対応します:
    • 属性の値が検索した値とは異なるフィールド
    • 属性が存在しない(あるいはヌル値を含む)フィールド

    例えば、以下のクエリは、Rexという名前ではない犬を飼っている人のレコードに加えて、犬を飼っていない人、あるいは名前のない犬を飼っている人のレコードも返します:

     QUERY BY ATTRIBUTE([People];[People]Animals;"dog.name";#;"Rex")

    その他の例:以下のクエリは、[Table]ObjectField 内で値がvalue ではないattribute2 属性を含むオブジェクトであるattribute1 属性を含んでいるオブジェクトを含んでいる全てのレコードに加え、attribute1attribute2 も含まないオブジェクトフィールドのレコードを返します:
     QUERY BY ATTRIBUTE([Table];[Table]ObjectField;"attribute1.attribute2";#;value)

    この原則は配列属性にも適用されます。例えば:

     QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].city";#;"paris")

    上記のクエリは、Parisに住所を持っていないPeopleのレコードを返します。

    属性が未定義であるレコードだけを特定して取得したい場合、空のオブジェクトを使用して下さい(例2を参照して下さい)。しかしながら配列内にてヌル値を検索することはサポートされていない点に注意していください。

  • ヌル値を空の値にマッププロパティがチェックされていない("SQL"モード)
    この場合、未定義の属性(フィールド内に存在しない属性、あるいは値がヌル)はデフォルトで空の値と同じではないと判断されます。結果として、"属性Aが属性Bと異なる"というタイプのクエリは、属性Aが未定義のレコードを返しません。
    [People]Animalsフィールドに対してヌル値を空の値にマップオプションがチェックされていない場合に、上記と同じ例を使用した場合、以下のクエリは名前("name"属性)が"Rex"ではない犬を持っている人のレコードのみを返します。この場合、犬を持っていない人、あるいは名前のない犬を持っている人のレコードは返されません。
     QUERY BY ATTRIBUTE([People];[People]Animals;"dog.name";#;"Rex")

    このSQLロジックに近いオペレーションは、特定の用途のために準備されている者です。

属性によるクエリを複数組み合わせる際には、以下のルールが適用されます:

  • 最初のクエリ文字列は接続子を含んではいけません。
  • その後のそれぞれのクエリ文字列は接続子から始まります。省略した場合mAND(&)演算子がデフォルトで使用されます。
  • 最初のクエリと、最後を除く他の全てのクエリは、 * 演算子を使用しなければなりません。
  • QUERY BY ATTRIBUTE コマンドはQUERY コマンドと組み合わせて使用することができます(例を参照して下さい)。
  • クエリを実行するためには、最後のQUERY BY ATTRIBUTE コマンドにおいて * 引数を指定してはいけません。その代り、QUERY コマンドをテーブルのみで(他の引数を必要とせず)実行する事ができます。

注: それぞれのテーブルは現在ビルトされたクエリを維持します。これはつまり、それぞれのテーブルに対して一つずつ、複数のクエリを同時に作成できるという事です。

どのように定義されたとしても、クエリには以下の制限がつきますNo matter which way a query has been defined:

  • 実際のクエリオペレーションが実行にある程度の時間が必要になる場合、4Dは自動的に進捗バー(サーモメーター)を含めたメッセージを表示します。このメッセージはMESSAGES ONMESSAGES OFF コマンドを使用することによってオン・オフを切り替えることができます。進捗バーが表示されているとき、ユーザーはストップボタンを押すことによってクエリを中断することができます。クエリが完了すると、OK変数が1に設定されます。それ以外の場合、例えがクエリが中断されたばあなどには、OK変数は0(ゼロ)に設定されます。
  • インデックスされたオブジェクトフィールドが指定された場合、クエリは毎回可能な限り最適化されるので(インデックスされたフィールドから先に検索されます)、結果として可能な限り最小限の時間でクエリを終えることができます。

日付はオブジェクト内において、データベース設定に沿った形で保存されています。デフォルトでは、タイムゾーンは考慮されます(SET DATABASE PARAMETER コマンドのJSON use local time を参照して下さい)。

!1973-05-22! -> "1973-05-21T23:00:00.000Z"

この設定はクエリにおいても影響するので、データベースを常に毎回同じ場所で使用し、データにアクセスる全てのマシンの設定が同じであれば何も心配する必要がありません。この場合、以下のクエリは、Birthday属性が!1973-05-22!("1973-05-21T23:00:00.00Z"として保存されている)に一致するレコードを正確に返します:

 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Birthday";=;!1973-05-22!)

GMT設定を使用したくない場合、これらの設定を以下の様にして変更する事ができます:

 SET DATABASE PARAMETER(JSON use local time;0)

ただし、この設定のスコープはプロセスのみであるという点に注意して下さい。設定をこのように変更した場合、1965年10月1日は"1965-10-01T00:00:00.000Z"として保存されますが、クエリを実行する前に同じ引数を設定する必要が出てきます:

 SET DATABASE PARAMETER(JSON use local time;0)
 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Birthday";=;!1976-11-27!)

このコマンドでは、仮想的な"長さ"プロパティを使用する事ができます。このプロパティは全ての配列型属性に対して自動的に利用可能で、配列のサイズ、つまり含まれる要素の数を返します。QUERY BY ATTRIBUTEコマンドを実行するコンテキストにおいて使用する事ができます(例第4を参照)。

この例においては、"age"属性は文字列か整数の値であり、年齢が20歳から29歳の人を検索したい場合を考えます。最初の2行は属性を整数としてクエリし(>=20 かつ < 30)、最後の1行はフィールドを文字列としてクエリします("2" で始まるが、"2"ではない値)。

 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"age";>=;20;*)
 QUERY BY ATTRIBUTE([Persons]; & ;[Persons]OB_Info;"age";<;30;*)
 QUERY BY ATTRIBUTE([Persons];|;[Persons]OB_Info;"age";=;"2@";*)
 QUERY BY ATTRIBUTE([Persons]; & ;[Persons]OB_Info;"age";#;"2") //実行したいので、ここでは最後の * は無い

QUERY BY ATTRIBUTE コマンドを使用すると、特定の属性が定義されている(あるいは定義されていない)レコードを探す事ができます。そのためには、空のオブジェクトを使用します。

  //オブジェクトフィールド内にてEメールが定義されているレコードを探す
 C_OBJECT($undefined)
 QUERY BY ATTRIBUTE([Persons];[Persons]Info;"e-mail";#;$undefined)

  //オブジェクトフィールド内にてZIPコード(郵便番号)が定義されていないレコードを探す
 C_OBJECT($undefined)
 QUERY BY ATTRIBUTE([Persons];[Persons]Info;"zip code";=;$undefined)

注: この特定のシンタックスは配列型属性ではサポートされていません。配列要素内でNULL値を検索した場合には不正な結果が返されます。

配列の属性を含むフィールドを検索したい場合を考えます。以下の二つのレコードがあった時、:

レコード1:
[People]name: "martin"
[People]OB_Field:
    "locations" : [ {
                "kind":"office",
                "city":"paris"
            } ]

レコード2:
[People]name: "smith"
[People]OB_Field:
    "locations" : [ {
                "kind":"home",
                "city":"lyon"
            } , {
                "kind":"office",
                "city":"paris"
            } ]

... QUERY BY ATTRIBUTE コマンドに対して以下の宣言をすると、locationが"paris"である人を探します:

  //配列の属性を".[]" シンタックスでフラグ付けする
 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations.[].city";=;"paris")
  //"martin" と "smith" を返す

注: 同じ配列の属性に対し複数の条件を定義した場合、合致した条件は必ずしも同じ配列の要素に対して適用されるとは限りません。以下の例においては、”kind"が"home"である”locations"要素と、"city"が"paris"である"locations"要素を持っているために"smith"が返されますが、これら二つは同じ要素ではありません:

 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations.[].kind";=;"home";*)
 QUERY BY ATTRIBUTE([People]; & ;[People]OB_Field;"locations.[].city";=;"paris")
  //"smith"を返す

この例題では、仮想的な"長さ"プロパティの使用について説明します。データベースには[Customer]full_Dataというオブジェクトフィールドがあり、以下のデータが入っているものとします:

子供が二人以上いる顧客のレコードを取得したい場合を考えます。この場合、以下のように書く事ができます:

 QUERY BY ATTRIBUTE([Customer];[Customer]full_Data;"Children.length";>=;2)

クエリが正しく実行されると、OKシステム変数が1に設定されます。以下の場合は0に設定されます:

  • クエリダイアログボックスでユーザがキャンセルボタンをクリックした。
  • "QUERY and LOCK"モード (SET QUERY AND LOCKコマンド参照)、クエリが一つ以上のロックされたレコードを見つけた。この場合、LockedSetシステムセットが更新されます。



参照 

4Dオブジェクトの構造
QUERY SELECTION BY ATTRIBUTE

 
プロパティ 

プロダクト: 4D
テーマ: クエリ
番号: 1331

このコマンドはOKシステム変数を更新しますこのコマンドはカレントレコードを変更しますこのコマンドはカレントセレクションを変更しますThis command can be run in preemptive processes

 
履歴 

初出: 4D v15

 
ARTICLE USAGE

ランゲージリファレンス ( 4D v16)
ランゲージリファレンス ( 4D v16.1)
ランゲージリファレンス ( 4D v16.2)
ランゲージリファレンス ( 4D v16.3)