Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

暗黙結合 (矢印構文)

Caché SQL には、関連するテーブルから値を取得するための省略手段として、特殊な –> 演算子があります。これにより、特定のケースで、明示的に JOIN を指定するという複雑な作業を省くことができます。この矢印構文を明示的な結合構文の代わりに使用したり、明示的な結合構文と組み合わせて使用したりできます。矢印構文は左外部結合を実行します。

Note:

暗黙結合構文 (矢印構文) と明示的結合構文との組み合わせの中には許可されないものがあります。ON 節では矢印構文 (–>) を使用できません。矢印構文 (–>) とシンボル結合構文 (*= および =*) の組み合わせでは、矢印構文を左外部結合 (=*) の右側、または右外部結合 (*=) の左側に使用することはできません。詳細は、"Caché SQL リファレンス" の "JOIN" のページを参照してください。

矢印構文は、クラスのプロパティまたは親テーブルのリレーションシップ・プロパティの参照に使用できます。その他のタイプのリレーションシップおよび外部キーでは矢印構文はサポートされません。

プロパティの参照

“参照されたテーブル” から値を取得するための省略手段として、–> 演算子を使用できます。

例えば、CompanyEmployee という 2 つのクラスを定義するとします。

Class Sample.Company Extends %Persistent [DdlAllowed]
{
/// The Company name
Property Name As %String;
}

また、Employee は以下のように定義します。

Class Sample.Employee Extends %Persistent [DdlAllowed]
{
/// The Employee name
Property Name As %String;

/// The Company this Employee works for
Property Company As Company;
}

Employee クラスは、Company オブジェクトへの参照のプロパティを含みます。オブジェクト・ベースのアプリケーションでは、ドット構文を使用してこの参照を表すことができます。例えば、会社員 (employee) が所属する会社 (company) を見つけるには、以下を使用します。

name = employee.Company.Name

SQL 文で同じ作業を実行するには、OUTER JOIN により EmployeeCompany のテーブルを結合します。

SELECT Sample.Employee.Name, Sample.Company.Name AS CompName
FROM Sample.Employee LEFT OUTER JOIN Sample.Company
ON Sample.Employee.Company = Sample.Company.ID

–> 演算子を使用すると、同様の OUTER JOIN 操作をより簡潔に実行できます。

SELECT Name, Company->Name AS CompName
FROM Sample.Employee

テーブルに参照列がある場合はいつでも –> 演算子を使用できます。この列の値は、参照されたテーブルの ID です (本来は、外部キーの特殊なケースです)。この場合は、Sample.Employee の Company フィールドには、Sample.Company テーブル内のレコードの ID が含まれています。クエリで列の式を使用できる場所であれば、どこでも –> 演算子を使用できます。例えば、以下の WHERE 節を考えます。

SELECT Name,Company AS CompID,Company->Name AS CompName
FROM Sample.Employee
WHERE Company->Name %STARTSWITH 'G'

これは以下と同じです。

SELECT E.Name,E.Company AS CompID,C.Name AS CompName
FROM Sample.Employee AS E, Sample.Company AS C
WHERE E.Company = C.ID AND C.Name %STARTSWITH 'G'

この場合、対応するクエリは INNER JOIN を使用しています。

以下の例では、矢印構文を使用して Sample.Person 内の Spouse フィールドにアクセスします。この例で示されるように、Sample.Employee 内の Spouse フィールドには、Sample.Person 内のレコードの ID が含まれています。この例では、従業員の Home_State または Office_State とその従業員の配偶者の Home_State が同じであるレコードを返します。

SELECT Name,Spouse,Home_State,Office_State,Spouse->Home_State AS SpouseState
FROM Sample.Employee
WHERE Home_State=Spouse->Home_State OR Office_State=Spouse->Home_State

GROUP BY 節で –> 演算子を使用できます。

SELECT Name,Company->Name AS CompName
FROM Sample.Employee
GROUP BY Company->Name

ORDER BY 節で –> 演算子を使用できます。

SELECT Name,Company->Name AS CompName
FROM Sample.Employee
ORDER BY Company->Name

または、ORDER BY 節で –> 演算子列の列エイリアスを参照します。

SELECT Name,Company->Name AS CompName
FROM Sample.Employee
ORDER BY CompName

以下の例で示すように、複合矢印構文がサポートされています。この例では、Cinema.Review テーブルには Film フィールドが含まれており、それには Cinema.Film テーブルの行 ID が含まれています。Cinema.Film テーブルには Category フィールドが含まれており、それには Cinema.Category テーブルの行 ID が含まれています。したがって、ReviewScore がある各フィルムの CategoryName を返すには、Film->Category->CategoryName によってこれら 3 つのテーブルにアクセスします。

SELECT ReviewScore,Film,Film->Title,Film->Category,Film->Category->CategoryName
FROM Cinema.Review
ORDER BY ReviewScore

子テーブルの参照

–> 演算子を使用して、子テーブルを参照できます。例えば、LineItems が Orders テーブルの子テーブルであるとき、以下を指定できます。

SELECT LineItems->amount
FROM Orders

Orders には、LineItems というプロパティはありません。LineItems は、amount フィールドが含まれる子テーブルの名前です。このクエリによって、各 Order 列の結果セットに複数の行が生成されます。これは、以下と同等です。

SELECT L.amount
FROM Orders O LEFT JOIN LineItems L ON O.id=L.custorder

ここで、custorder は、LineItems テーブルの親参照フィールドです。

矢印構文の特権

矢印構文を使用する場合、両方のテーブルの参照対象データに対する SELECT 特権が必要です。テーブルレベルの SELECT 特権、または参照対象列に対する列レベルの SELECT 特権が必要です。列レベルの特権では、参照対象テーブルの ID および参照対象列に対する SELECT 特権が必要です。

以下の例は、必要な列レベルの特権を示しています。

SELECT Name,Company->Name AS CompanyName
FROM Sample.Employee
GROUP BY Company->Name
ORDER BY Company->Name

上記の例では、Sample.Employee.NameSample.Company.Name、および Sample.Company.ID に対して列レベルの SELECT 特権が必要です。

  ZNSPACE "SAMPLES"
  SET tStatement = ##class(%SQL.Statement).%New()
  SET privchk1="%CHECKPRIV SELECT (Name,ID) ON Sample.Company"
  SET privchk2="%CHECKPRIV SELECT (Name) ON Sample.Employee"
CompanyPrivTest
  SET qStatus = tStatement.%Prepare(privchk1)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
  IF rset.%SQLCODE=0 {WRITE !,"have Company privileges",! }
  ELSE {  WRITE !,"No privilege: SQLCODE=",rset.%SQLCODE,! }
EmployeePrivTest
  SET qStatus = tStatement.%Prepare(privchk2)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
  IF rset.%SQLCODE=0 {WRITE !,"have Employee privilege",! }
  ELSE {  WRITE !,"No privilege: SQLCODE=",rset.%SQLCODE }
FeedbackOpens in a new tab