データベースからの読み取り
データベース内のテーブルからデータを取得することは、一般的に "選択" や "フェッチ" と呼ばれていますが、Eggplant Functional とデータベースを使用する場合は "読み取り" データと呼ばれます。この返されたデータは、Eggplant Functional を用いたデータ駆動型テストなどのテストに情報を提供するために使用することができます。
テーブル内容の読み取り
データベーステーブルの内容をフェッチすることは、そのすべてのレコードを要求するだけの単純な作業となることがあります。
データベースを変更する必要がなく、ただ読み取りたいだけの場合は、writable
データベース接続リストプロパティを No
に設定してください。
例:
以下のコードは、Members
変数をレコードのリストに設定します。それぞれの行に対して一つのレコードがリスト内に格納されます。リスト内の各アイテムは Record
オブジェクトで、テーブル内のその行の値を含むプロパティリストであり、テーブル内の各列に対してプロパティキーが存在します。Recordsについての詳細は、Records vs. Property Listsを参照してください。
put the records of memberTable into Members
単一のレコードだけが期待されるか、必要な場合、record
を records
の代わりに使用することができます。これにより、レコードのリストではなく、単一のレコードオブジェクトが返されます。
この例のように、大きなテーブルの全てのレコードを変数に読み込むことは推奨されません。where
式を使用するか、データベースのレコードをイテレーションする方法を参照してレコードをイテレーションしてください。
例:
この例では、Get
コマンドを使用して、lastName列が "Smith" と等しいレコードのデータのみを取得します。where
節は、レコードを選択するためのさまざまな基準を含めることができます。
get the records of memberTable where lastName is "Smith"
名前 が "S" で始まるが、 "Smith" を除くすべてのレコードを取得するには、次のようにリクエストします:
get records of memberTable where lastName begins with "S" and lastName isn't "Smith"
例:
Get
コマンドはまた、それ(参照:すべてについて "It")と一緒に使用することもできます:
set myDB to {type:"odbc", DSN:"MyDB"} -- データベース接続を定義
put table "film" of myDB into myTable -- 変数 myTable に特定のテーブルへの参照データを格納
get rental_rate of the record of myTable where title is "TERMINATOR" -- Get コマンドを使用して特定の映画のレンタル料を取得
if it is "$9.99" then log "Rental rate is correct!" -- ローカル変数 It を使用してレンタル料が正しいことを確認
Where式
データベーステーブルには、大量のレコード(数千、数十万、それ以上)が含まれている場合があります。このような大きさのテーブル全体をEggplant Functionalの変数に取り込むと、ローカルメモリの使用に影響を及ぼす可能性があります。このため、必要なレコードだけを要求で きると便利なことがよくあります。where
節はこれを実現し、必要なレコードだけをデータベースに要求することで、ネットワークトラフィックとローカルメモリ使用量の両方を最小限に抑えます。
Where
式は、record
またはrecords
関数、number of records
関数、またはdelete record
コマンドを使用して、テーブルから必要なレコードを選択するために使用されます。where
節が指定されていない場合、テーブルのすべてのレコードが返されます。
このページで説明されているwhere
節は、Each Expressionsで使用されるwhere
節と混同しないでください。それらは似たようなことをしますが、非常に異なります。データベースで使用されるwhere
式は能力が限られていますが、データベースからデータを取得する際にははるかに効率的になることができます。
where式はwhere
節に続く式で構成されます。その式には、_columnName operator value_の形式を使用してテーブルを1つ以上参照するものが含まれます。列の名前は最初に来て、その後にオペレータ、そして値が続きます。たとえば、式 "where size is at least 12"では、列名は "size"、オペレータは "is at least"、値は "12"です。
例:
set mymovie to the record of films where title is "TERMINATOR"
where節で指定した条件に一致するレコードが複数ある場合、record
という語を使用すると、その中の最初のレコードのみが返されます。一致するすべてのレコードを返すにはrecords
を使用します。
オペレーター
where
式を使用する場合、オペレーターは次のいずれか(またはそれらの同義語や否定形)にすることができます:
- is equal to
- is not equal to
- is less than
- is more than
- is less than or equal to
- is greater than or equal to
- begins with
- ends with
- contains substring
- is in list of values
- is between min and max
これらのオペレータは、列に値が割り当てられているかどうかをテストするために使用できます:
- columnName is null
- columnName is not null
And/Or
さらに、AND
またはOR
で条件を結合することで、複数の条件を一度にテストすることができます。複雑なwhere
式では、括弧でサブ式を囲む と意味が明確になります。
例:
delete records from billingTable where (dueDate is earlier than today) and (remainingAmountDue is 0)
例:
//Displays the full name of the club member whose member number is 12345
put 12345 into desiredMemNum
set clubDBto (type:"odbc", DSN:"ClubData", user:"root", password:"")
put table "Members" of clubDB into memberTable
set member to the record of memberTable where memberNumber is desiredMemNum
put "Name: " & member's firstName && member's lastName
データベーステーブルのレコードを繰り返し処理する
データベーステーブルのレコードを繰り返し処理することは、レコードを更新したりデータを操作したりする一般的な方法です。これは、Repeat LoopまたはRecord Iteratorを使用して行うことができます。
Repeat Loopを使用する
SenseTalkのrepeat loopを使用してデータを繰り返し処理するためには、そのデータをデータベースから読み込んでスクリプトに取り込む必要があります。その後、他のSenseTalkスクリプトと同様に、取得したデータを繰り返し処理するためのrepeat loopを使用できます。
レコードを繰り返し処理し、反復処理中に修正を加える必要があるシナリオでは、Repeat with Each... By Referenceを使用します。これはReferences to Containersで説明されています。
例:
以下の例では、repeat loopを使用してデータベースから取得したユーザレコードを繰り返し処理し、各ユーザーのためのオンラインフォームを記入します:
set myDB to {type:"odbc", DSN:"mySQLDB", user:"root", password:"password123"} -- データベース接続情報を定義する
put the number of records in table "userInfo" in myDB into numRecords -- テーブル内のレコード総数を読み取り、その情報を変数numRecordsに格納する
Log "We will be entering" && numRecords && "records into the system." -- 何レコード利用可能かを宣言するメッセージをログに記録する
put table "userInfo" of myDB into users -- データベーステーブル"userInfo"へのアクセス情報を変数"users"に格納する
put the records of users into credentials -- "userInfo"テーブルからレコードを取得し、それらを変数credentialsに格納する
Log "Entering the following new users: " & credentials -- レコード自体を含むメッセージをログに記録する
repeat with each item user of credentials -- credentialsの各レコードに基づいて繰り返す
WaitFor 10, "Form_SubmitButton"
Click "Form_UsernameField"
typetext user.username -- 現在のレコードのusernameプロパティの値を参照し、その値をSUTに入力する
Click "Form_PasswordField"
typetext user.password
Click "Form_SubmitButton"
Click "Form_AddNewUser"
end repeat
例:
プロパティリストは、キーを使用して値を特定するリストです(詳細はプロパティリストを参照)。この例では、プロパティキーがどのようにしてデータの異なる部分を特定し、操作するために使用できるかを示しています。これは単独の例で、実際にはデータベースに接続する必要はありませんので、ご自身のシステムで実行してみてください。
// カラム名でアイテムキーを使用する
set dbResults to { {name:"Roger", age:17}, {name:"Arabella", age:32}, {name:"Francis", age:29}, {name:"Balthazar", age:92},
}
put the keys of item 1 of dbResults into columnNames
put columnNames
put columnNames joined by comma into header
put header & return into csvContents
repeat with each record of dbResults
repeat with each key in columnNames
if the counter > 1 then put comma after csvContents
put record.(key) after csvContents
end repeat
put return after csvContents
end repeat
put csvContents
以下は、前述の例の短縮版であり、データベースに接続せずに実行するために書かれたものであり、デモンストレーション目的のため、ご自身のマシンで実行してみてください。
// カラム名でアイテムキーを使用する
set dbResults to{ {name:"Roger", age:17}, {name:"Arabella", age:32}, {name:"Francis", age:29}, {name:"Balthazar", age:92},
}
put the keys of item 1 of dbResults joined by comma & return into csvContents
repeat with each record of dbResults
put values(record) joined by comma & return after csvContents
end repeat
put csvContents
レコードイテレータの使用
テーブルから一連のレコードをリストとして取得する代わりに、一度に1つのレコードを反復処理する_レコードイテレータ_を取得することができます。イテレータをリストとして扱う(as a list
演算子を使用する場合など)と、残りのすべてのレコードがフェッチされます。レコードイテレータは、一部の状況で便利であるかもしれませんが、全てのデータが一度にデータベースからフェッチされ、要求された時にのみレコードオブジェクトに変換されるため、repeatループと比べて非常に小さいパフォーマンス上の利点しか提供しません。SenseTalkのイテレータについての詳細は、Iteratorsを参照してください。
SenseTalkでレコードイテレータにアクセスする方法は2つあります。
useRecordIteratorプロパティの設定
可能な場合にはレコードイテレータを返すようにuseRecordIterator
プロパティをtrueに設定します。
set the useRecordIterator of myTable to Yes
直接イテレータを要求する
直接イテレータを要求するためには、データベースリクエスト内で"iterate over the records of"を使用します。
set memberIterator to iterate over the records of memberTable
次のレコードは、イテレータのnextValue
プロパティを使用して取得することができます。
put memberIterator's nextValue into currentMember
データベーステーブルのレコード数をカウントする
データベーステーブルのレコード数をカウントするには、Number of Records
関数を使用します。
Number of Records
関数
振る舞い: 指定されたテーブルのレコード数を返します。Records
またはRows
のどちらでも交換可能に使用できます。
パラメータ: テーブル。テーブルを参照するtable
表現または変数とペアにする必要があります。
文法:
{the} number of [rows | records] [of | in] table {where whereExpr}
上記の構文中の_Table_は、テーブルを参照に設定した変数、またはtable
表現(table tablename of database)のどちらかです。
例:
テーブルの_レコード数_を直接尋ねると、データベースに_count_リクエストが送信されます。カウントリクエストは、レコードではなく数値を返します。これは、レコードをフェッチして返されたリストのアイテム数を尋ねるよりも効率的です。これは、大量のレコードを含むテーブルを操作するときに安全な方法です。この例では、データベーステーブルに何レコードがあるかを調べるためにnumber of records
を使用してい ます。
put the number of records of table "colorpalette" of myDB
例:
データベーステーブルで特定の条件に一致するレコードがいくつあるかを調べる別の方法は、テーブル参照を変数に保存し、次にnumber of records
関数を、オプションのwhere
句(Where Expressions参照)と共にテーブル変数に適用することです。次の例を参照してください。
put table "colorpalette" of myDB into colors -- Stores a reference to the table in a variable.
get number of records of colors where color is "green" --
Log "There are " & it & " record(s) in the table."
Log "There are " & it & " record(s) in the table.":
小さいテーブルを扱うのに適した別の方法です。この方法はよりシンプルですが、慎重に使用する必要があります。また、すべてのレコードをSenseTalkに持ち込みたいと知っている場合に使用します。
put the records of table "memberinfo" of myDB into members
put the number of items in members
例:行数の変化の数
レコード(行)数の行数のバリエーションを使用して、データベーステーブル内で特定の条件に一致するレコードが何件あるかを調べます:
put the number of rows of table "colorpalette" of myDB where "color" is "black"
例:
テスト実行の開始時に追加されるレコード数を宣言するために、number of records
関数を使用します:
set myDB to (type:"odbc", DSN:"mySQLDB", user:"root", password:"password123")
put the number of records in table "users" in myDB into numRecords -- Stores the total number of records in the table into variable numRecords
Log "We will be entering" && numRecords && "records into the system." -- Logs a message to declare how many records are available