@LINK Directive

The @LINK directive disambiguates multiple foreign-key relationships between tables or to specify self-referencing foreign keys within the same table.

It explicitly defines which foreign key to use when joining or linking tables in both table function and duality view. Normally, foreign key links are automatically inferred, so you don't always need to specify @link. Using @link directive is necessary when there are no foreign-key constraints defined, or there are multiple foreign-key relations between the same two tables, or a table's foreign key references itself (self-referencing).

If no foreign key constraints exist between the relevant tables, you must use the @link directive with both from and to arguments to explicitly specify the joining columns. If a foreign key constraint does exist, and there is only one possible relationship, @link is optional and Oracle will infer the correct columns to join on automatically. However, if there are multiple possible foreign key relationships between the same tables, or the relationship is ambiguous, use @link to specify which foreign key to use.

@link accepts either the from or to argument, or both.
  • from - Specifies the column(s) in the source table or object from which the link originates.
  • to - Specifies the column(s) in the target table or object to which the link connects.
When there is ambiguity regarding which foreign key to use or its direction, you must specify at least one of from or to to clarify the relationship. However, if there are no foreign key constraints defined between the tables, you should provide both from and to to explicitly specify how the tables should be joined.
Recall from the Setting up the Car Racing Dataset, that the table drivers had a foreign key team_id that references to the team_id column in the teams table.
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));

The following example uses @link directive to explicitly specify the joining columns:

Example 3-1 @link Directive Specifying the Joining Columns

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
        }
    }
');
Note that the square brackets in the @link are optional unless you specify composite joining columns. The above example, with or without square brackets will produce the same output:
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 directive is commonly used in creating JSON-Relational Duality View using GraphQL. See this section for a detailed example.

@link Directive to Identify a Foreign-Key Relation That References the Same Table

To understand this scenario, create and insert data a new table that has a foreign-key that references to the same table.

Example 3-2 Create and Insert Data to a New Table that has a Self-Referencing Field

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
        }
    }
');