クラス・クエリの定義と使用
このページでは、クラス・クエリを定義して使用する方法について説明します。クラス・クエリは、ダイナミック SQL の形式で、%SQL クラスを介して使用されます。
クラス・クエリの概要
クラス・クエリとは、ダイナミック SQL と共に使用することを目的として、クラスに含まれているツールです。これにより、指定した条件を満たすレコードを検索します。クラス・クエリを使用すると、アプリケーションに応じて事前に定義した検索を作成できます。例えば、名前でレコードを検索したり、特定の条件のセット (パリからマドリッドまでのすべての航空便など) を満たすレコードのリストを提供したりできます。
クラス・クエリを作成することで、特定のオブジェクトの内部 ID を使用してそのオブジェクトを検索せずに済むようになります。その代わりに、必要とするクラス・プロパティに基づいてレコードを検索するクエリを作成できます。これは、実行時にユーザによって指定することも可能です。
カスタム・クラス・クエリを定義すると、検索ロジックに ObjectScript を使用することも、検索ロジックを任意の複合式にすることもできます。
クラス・クエリには、以下の 2 種類があります。
-
基本クラス・クエリ。クラス %SQLQueryOpens in a new tab と SQL SELECT 文を使用します。
-
カスタム・クラス・クエリ。クラス %QueryOpens in a new tab と、カスタム・ロジック (クエリを実行、フェッチ、およびクローズするためのロジック) を使用します。これらについては別途説明します。
クラス・クエリはどのクラス内でも定義できます。クラス・クエリは永続クラス内に含める必要はありません。
別のクラス・クエリの結果に依存するクラス・クエリを定義することはできますが、クエリでは ROWSPEC パラメータを指定する必要があります。
クラス・クエリの使用法
クラス・クエリを定義する方法について説明する前に、その使用方法を知っておくと便利です。サーバ側のコードでは、以下のようにクラス・クエリを使用できます。
-
%New() を使用して、%SQL.StatementOpens in a new tab のインスタンスを作成します。
-
そのインスタンスの %PrepareClassQuery() メソッドを呼び出します。引数として、以下をこの順番で使用します。
-
使用するクエリを定義しているクラスの完全修飾名。
-
そのクラスに含まれるクエリの名前。
このメソッドは %StatusOpens in a new tab 値を返すので、その値を確認する必要があります。
-
-
%SQL.StatementOpens in a new tab インスタンスの %Execute() メソッドを呼び出します。これにより %SQL.StatementResultOpens in a new tab のインスタンスが返されます。
-
%SQL.StatementResultOpens in a new tab のメソッドを使用して、結果セットからデータを取得します。詳細は、"ダイナミック SQL の使用" を参照してください。
以下に、Sample.Person の ByName クエリを使用する簡単な例を示します。
// classquerydemo
set statement = ##class(%SQL.Statement).%New()
set status = statement.%PrepareClassQuery("Sample.Person","ByName")
if $$$ISERR(status) {
write "%Prepare failed:" do $SYSTEM.Status.DisplayError(status)
quit
}
set rset = statement.%Execute()
if (rset.%SQLCODE '= 0) {
write "%Execute failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message
quit
}
while rset.%Next()
{
write !, rset.%Get("Name")
}
if (rset.%SQLCODE < 0) {
write "%Next failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message
quit
}
ストアド・プロシージャとしてクエリを呼び出して、それを SQL コンテキストから実行することもできます。"ストアド・プロシージャの定義と使用" を参照してください。
基本クラス・クエリの定義
基本クラス・クエリを定義するには、以下のようにクエリを定義します。
-
(単純なクラス・クエリの場合) タイプは %SQLQueryOpens in a new tab にする必要があります。
-
オプションで、ROWSPEC など、%SQLQueryOpens in a new tab のパラメータを指定します。クエリの ROWSPEC パラメータでは、各行に含まれるフィールドの名前、データ型、ヘッダ、および順序に関する情報を提供します。詳細は、"クラス・クエリのパラメータ" を参照してください。
-
引数リストに、クエリが受け入れる引数を指定します。
-
定義の本文に、SQL SELECT 文を記述します。
この文では、引数名の先頭にコロン (:) を付けて、引数を参照します。
この SELECT 文には、INTO 節を含めないでください。
-
クエリ定義に SqlProc キーワードを含めます。
-
オプションとして、ストアド・プロシージャに既定の名前とは別の名前を付ける場合は、クエリ定義内で SqlName キーワードを指定します。
これらは、コンパイラ・キーワードであるため、クエリ・タイプ (%SQLQueryOpens in a new tab) の後のパラメータに続く角括弧の内側に含めます。
クラス・クエリのパラメータ
ここでは、カスタム・クラス・クエリ内で指定するパラメータの詳細について説明します。
ROWSPEC パラメータ
クエリの ROWSPEC パラメータでは、各行に含まれるフィールドの名前、データ型、ヘッダ、および順序に関する情報を提供します。これらの変数名は、引用符付きのコンマ区切りのリストで、データ型の形式は以下のとおりです。
ROWSPEC = "Var1:%Type1,Var2:%Type2[:OptionalDescription],Var3"
ROWSPEC は、コンマ区切りのリストとしてフィールドの順序を指定します。各フィールドの情報は、そのフィールドの名前、データ型 (対応するプロパティのデータ型と異なる場合)、およびヘッダ (オプション) をコロンで区切ったリストで構成されています。
ROWSPEC パラメータの要素数は、クエリのフィールド数と一致している必要があります。数が異なる場合、InterSystems IRIS® データ・プラットフォームは Cardinality Mismatch エラーを返します。
例えば、Sample.Person クラスの ByName クエリは以下のようになります。
Query ByName(name As %String = "")
As %SQLQuery(CONTAINID = 1, ROWSPEC = "ID:%Integer,Name,DOB,SSN", SELECTMODE = "RUNTIME")
[ SqlName = SP_Sample_By_Name, SqlProc ]
{
SELECT ID, Name, DOB, SSN
FROM Sample.Person
WHERE (Name %STARTSWITH :name)
ORDER BY Name
}
ここでは、最初のフィールドが行 ID (既定) であることを CONTAINID パラメータで指定しています。SELECT 文で指定されている最初のフィールドも ID である点に注意してください。ROWSPEC パラメータでは、各フィールドが ID (整数として処理される)、Name、DOB、および SSN であることを指定しています。同様に、SELECT 文にも ID、Name、DOB、および SSN の各フィールドが、この順序で含まれています。
CONTAINID パラメータ
CONTAINID は、ID を返す列の番号 (既定では 1) に設定する必要があります。ID を返す列がない場合は 0 に設定します。
システムは CONTAINID の値を検証しません。ユーザがこのパラメータに対して無効な値を指定した場合でも、エラー・メッセージは発行されません。つまり、ユーザのクエリ処理ロジックがこの情報に基づいている場合で、CONTAINID パラメータが不正に設定されているときは、不整合が生じる可能性があります。
クエリ・クラスのその他のパラメータ
ROWSPEC と CONTAINID に加え、以下に示すクエリのパラメータも指定できます。これらは、%SQLQueryOpens in a new tab のクラス・パラメータです。
-
SELECTMODE
-
COMPILEMODE
詳細は、%Library.SQLQueryOpens in a new tab と、そのスーパークラス %Library.QueryOpens in a new tab のクラスリファレンスを参照してください。
例
以下に簡単な例を示します。
Query ListEmployees(City As %String = "")
As %SQLQuery (ROWSPEC="ID:%Integer,Name:%String,Title:%String", CONTAINID = 1) [SqlProc, SqlName=MyProcedureName]
{
SELECT ID,Name,Title FROM Employee
WHERE (Home_City %STARTSWITH :City)
ORDER BY Name
}
文字列パラメータの最大長
ADO.NET、ODBC、または JDBC を使用してクラス・クエリを呼び出す場合、既定では、文字列パラメータが 50 文字に切り捨てられます。パラメータの最大文字列長を長くするには、以下の例のようにシグニチャで MAXLEN を指定します。
Query MyQuery(MyParam As %String(MAXLEN = 200)) As %SQLQuery [SqlProc]
管理ポータルまたは ObjectScript からクエリを呼び出す場合、この切り捨ては行われません。