@LINKディレクティブ
@LINKディレクティブは、表間の複数の外部キー関係の曖昧さを排除したり、同じ表内の自己参照外部キーを指定します。
表関数と二面性ビューの両方で、表を結合またはリンクする際に使用する外部キーを明示的に定義します。通常、外部キー・リンクは自動的に推測されるため、常に@linkを指定する必要があるわけではありません。外部キー制約が定義されていない場合、同じ2つの表間に複数の外部キー関係がある場合、または表にその表自体に対する外部キー参照がある(自己参照)場合は、@linkディレクティブを使用する必要があります。
関連する表の間に外部キー制約が存在しない場合は、@linkディレクティブをfromとtoの両方の引数とともに使用して、結合列を明示的に指定する必要があります。外部キー制約が存在し、可能な関係が1つのみの場合、@linkはオプションであり、Oracleによって自動的に結合する正しい列が推測されます。ただし、同じ表間に可能な外部キー関係が複数ある場合、または関係があいまいな場合は、@linkを使用して、使用する外部キーを指定します。
@linkは、from引数またはto引数、あるいはその両方を受け取ります。
from- リンク元のソース表またはオブジェクトの列を指定します。to- リンクの接続先となるターゲット表またはオブジェクトの列を指定します。
fromまたはtoのうち少なくとも1つを指定する必要があります。ただし、表の間に外部キー制約が定義されていない場合は、fromとtoの両方を指定して、表の結合方法を明示的に指定する必要があります。
drivers表に、teams表のteam_id列を参照する外部キーteam_idがあったことを思い出してください。CREATE TABLE driver
(driver_id INTEGER PRIMARY KEY,
name VARCHAR2(255) NOT NULL UNIQUE,
points INTEGER NOT NULL,
team_id INTEGER,
CONSTRAINT driver_fk FOREIGN KEY(team_id) REFERENCES team(team_id));次の例では、@linkディレクティブを使用して結合列を明示的に指定します:
例3-1 結合列を指定する@linkディレクティブ
SELECT JSON_SERIALIZE(data PRETTY) AS data FROM GRAPHQL('
team {
teamId: team_id
teamName: name
teamPoints: points
drivers: driver @link(from: ["TEAM_ID"], to: ["TEAM_ID"]) {
driverId: driver_id
driverName: name
driverPoints: points
}
}
');
@linkの角括弧はオプションです。前述の例では、角括弧の有無にかかわらず、同じ出力が生成されます:DATA
--------------------------------------------------------------------------------
{
"teamId" : 301,
"teamName" : "McLaren Mercedes",
"teamPoints" : 666,
"drivers" :
[
{
"driverId" : 101,
"driverName" : "Lando Norris",
"driverPoints" : 282
},
{
"driverId" : 102,
"driverName" : "Oscar Piastri",
"driverPoints" : 384
}
]
}
{
"teamId" : 302,
"teamName" : "Ferrari",
"teamPoints" : 652,
"drivers" :
[
{
"driverId" : 103,
"driverName" : "Charles Leclerc",
"driverPoints" : 312
},
{
"driverId" : 104,
"driverName" : "Carlos Sainz Jr.",
"driverPoints" : 340
}
]
}
..............................
..............................
10 rows selected.@linkディレクティブは、通常、GraphQLを使用したJSONリレーショナル二面性ビューの作成に使用されます。詳細な例については、この項を参照してください。
同じ表を参照する外部キー関係を識別するための@linkディレクティブ
このシナリオを理解するために、同じ表を参照する外部キーを持つ新しい表を作成してデータを挿入します。
例3-2 自己参照フィールドを持つ新しい表の作成およびデータの挿入
CREATE TABLE driver_w_lead
(driver_id INTEGER PRIMARY KEY,
name VARCHAR2(255) NOT NULL UNIQUE,
points INTEGER NOT NULL,
team_id INTEGER,
lead_driver_id INTEGER,
CONSTRAINT driver_w_lead_team_fk FOREIGN KEY(team_id) REFERENCES team(team_id),
CONSTRAINT driver_w_lead_fk FOREIGN KEY(lead_driver_id) REFERENCES driver_w_lead(driver_id));
INSERT INTO driver_w_lead (driver_id, name, points, team_id, lead_driver_id) VALUES
(101, 'Lando Norris', 282, 301, NULL),
(102, 'Oscar Piastri', 384, 301, 101),
(103, 'Charles Leclerc', 312, 302, NULL),
(104, 'Carlos Sainz Jr.', 340, 302, 103),
(105, 'Max Verstappen', 456, 303, NULL),
(106, 'Sergio Pérez', 133, 303, 105),
(107, 'Lewis Hamilton', 240, 304, NULL),
(108, 'George Russell', 228, 304, 107),
(109, 'Fernando Alonso', 58, 305, NULL),
(110, 'Lance Stroll', 36, 305, 109),
(111, 'Esteban Ocon', 33, 306, NULL),
(112, 'Pierre Gasly', 32, 306, 111),
(113, 'Nico Hülkenberg', 30, 307, NULL),
(114, 'Kevin Magnussen', 28, 307, 113),
(115, 'Daniel Ricciardo', 24, 308, NULL),
(116, 'Yuki Tsunoda', 22, 308, 115),
(117, 'Alexander Albon', 12, 309, NULL),
(118, 'Logan Sargeant', 5, 309, 117),
(119, 'Valtteri Bottas', 3, 310, NULL),
(120, 'Zhou Guanyu', 1, 310, 119);
SELECT JSON_SERIALIZE(data PRETTY) AS data FROM GRAPHQL('
driver_w_lead {
id: driver_id
name
points
team @unnest {
teamName: name
}
driver_w_lead @link(from: lead_driver_id) @unnest {
leadDriver: name
}
}
');