关于Oracle主外键约束的几个SQL语句
示例为Oracle Database Sample Schema中的HR schema。
表之间关系如下:
从employees表视角看到的关联关系(References部分):
SQL> info hr.employees
TABLE: EMPLOYEESLAST ANALYZED:2025-09-18 13:00:14.0ROWS :106SAMPLE SIZE :106INMEMORY :DISABLEDCOMMENTS :employees table. Contains 107 rows. References with departments,jobs, job_history tables. Contains a self reference.Columns
NAME DATA TYPE NULL DEFAULT COMMENTS
*EMPLOYEE_ID NUMBER(6,0) No Primary key of employees table.FIRST_NAME VARCHAR2(20 BYTE) Yes First name of the employee. A not null column.LAST_NAME VARCHAR2(25 BYTE) No Last name of the employee. A not null column.EMAIL VARCHAR2(25 BYTE) No Email id of the employeePHONE_NUMBER VARCHAR2(20 BYTE) Yes Phone number of the employee; includes countrycode and area codeHIRE_DATE DATE No Date when the employee started on this job. A notnull column.JOB_ID VARCHAR2(10 BYTE) No Current job of the employee; foreign key to job_idcolumn of thejobs table. A not null column.SALARY NUMBER(8,2) Yes Monthly salary of the employee. Must begreaterthan zero (enforced by constraintemp_salary_min)COMMISSION_PCT NUMBER(2,2) Yes Commission percentage of the employee; Onlyemployees in salesdepartment elgible forcommission percentageMANAGER_ID NUMBER(6,0) Yes Manager id of the employee; has same domain asmanager_id indepartments table. Foreign key toemployee_id column of employees table.(useful forreflexive joins and CONNECT BY query)DEPARTMENT_ID NUMBER(4,0) Yes Department id where employee works; foreign key todepartment_idcolumn of the departments tableIndexes
INDEX_NAME UNIQUENESS STATUS FUNCIDX_STATUS COLUMNS
HR.EMP_JOB_IX NONUNIQUE VALID JOB_ID
HR.EMP_NAME_IX NONUNIQUE VALID LAST_NAME, FIRST_NAME
HR.EMP_EMAIL_UK UNIQUE VALID EMAIL
HR.EMP_EMP_ID_PK UNIQUE VALID EMPLOYEE_ID
HR.EMP_MANAGER_IX NONUNIQUE VALID MANAGER_ID
HR.EMP_DEPARTMENT_IX NONUNIQUE VALID DEPARTMENT_IDReferences
TABLE_NAME CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE VALIDATED GENERATED
CUSTOMERS CUSTOMERS_ACCOUNT_MANAGER_FK SET NULL ENABLED NOT DEFERRABLE VALIDATED USER NAME
DEPARTMENTS DEPT_MGR_FK NO ACTION ENABLED NOT DEFERRABLE VALIDATED USER NAME
EMPLOYEES EMP_MANAGER_FK NO ACTION ENABLED NOT DEFERRABLE VALIDATED USER NAME
JOB_HISTORY JHIST_EMP_FK NO ACTION ENABLED NOT DEFERRABLE VALIDATED USER NAME
ORDERS ORDERS_SALES_REP_FK SET NULL ENABLED NOT DEFERRABLE VALIDATED USER NAME
表的所有主外键
SQL 如下:
SELECT c.constraint_name,c.constraint_type,col.column_name,col.position,c.r_constraint_name AS referenced_constraint,r.table_name AS referenced_table
FROM all_constraints c
JOIN all_cons_columns colON c.constraint_name = col.constraint_name
LEFT JOIN all_constraints rON c.r_constraint_name = r.constraint_name
WHERE c.table_name = UPPER('&1')
AND c.constraint_type IN ('P', 'R')
ORDER BY c.constraint_type, c.constraint_name, col.position;
以表employees为例,输出为:
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION REFERENCED_CONSTRAINT REFERENCED_TABLE
EMP_EMP_ID_PK P EMPLOYEE_ID 1
EMP_DEPT_FK R DEPARTMENT_ID 1 DEPT_ID_PK DEPARTMENTS
EMP_JOB_FK R JOB_ID 1 JOB_ID_PK JOBS
EMP_MANAGER_FK R MANAGER_ID 1 EMP_EMP_ID_PK EMPLOYEES
其中P表示主键,R表示外键。
另外可以看到,外键EMP_MANAGER_FK参照的主键在同一张表。
以下为另外3张表的输出:
SQL> /
Enter value for 1: jobs
old 12: WHERE c.table_name = UPPER('&1')
new 12: WHERE c.table_name = UPPER('jobs')
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION REFERENCED_CONSTRAINT REFERENCED_TABLE
JOB_ID_PK P JOB_ID 1SQL> /
Enter value for 1: departments
old 12: WHERE c.table_name = UPPER('&1')
new 12: WHERE c.table_name = UPPER('departments')
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION REFERENCED_CONSTRAINT REFERENCED_TABLE
DEPT_ID_PK P DEPARTMENT_ID 1
DEPT_LOC_FK R LOCATION_ID 1 LOC_ID_PK LOCATIONS
DEPT_MGR_FK R MANAGER_ID 1 EMP_EMP_ID_PK EMPLOYEESSQL> /
Enter value for 1: job_history
old 12: WHERE c.table_name = UPPER('&1')
new 12: WHERE c.table_name = UPPER('job_history')
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION REFERENCED_CONSTRAINT REFERENCED_TABLE
JHIST_EMP_ID_ST_DATE_PK P EMPLOYEE_ID 1
JHIST_EMP_ID_ST_DATE_PK P START_DATE 2
JHIST_DEPT_FK R DEPARTMENT_ID 1 DEPT_ID_PK DEPARTMENTS
JHIST_EMP_FK R EMPLOYEE_ID 1 EMP_EMP_ID_PK EMPLOYEES
JHIST_JOB_FK R JOB_ID 1 JOB_ID_PK JOBS
与主键关联的所有外键
SQL如下:
SELECT fk.owner AS fk_owner,fk.table_name AS fk_table,fkc.column_name AS fk_column,fk.constraint_name AS fk_name,pk.owner AS pk_owner,pk.table_name AS pk_table,pkc.column_name AS pk_column,pk.constraint_name AS pk_name
FROM all_constraints fk
JOIN all_constraints pkON fk.r_constraint_name = pk.constraint_nameAND fk.r_owner = pk.owner
JOIN all_cons_columns fkcON fk.owner = fkc.ownerAND fk.constraint_name = fkc.constraint_name
JOIN all_cons_columns pkcON pk.owner = pkc.ownerAND pk.constraint_name = pkc.constraint_nameAND fkc.position = pkc.position
WHERE fk.constraint_type = 'R'AND pk.constraint_type IN ('P','U')AND pk.constraint_name = '&1'
ORDER BY fk.owner, fk.table_name, fk.constraint_name;
示例输出如下:
Enter value for 1: EMP_EMP_ID_PK
old 23: AND pk.constraint_name = '&1'
new 23: AND pk.constraint_name = 'EMP_EMP_ID_PK'
FK_OWNER FK_TABLE FK_COLUMN FK_NAME PK_OWNER PK_TABLE PK_COLUMN PK_NAME
HR DEPARTMENTS MANAGER_ID DEPT_MGR_FK HR EMPLOYEES EMPLOYEE_ID EMP_EMP_ID_PK
HR EMPLOYEES MANAGER_ID EMP_MANAGER_FK HR EMPLOYEES EMPLOYEE_ID EMP_EMP_ID_PK
HR JOB_HISTORY EMPLOYEE_ID JHIST_EMP_FK HR EMPLOYEES EMPLOYEE_ID EMP_EMP_ID_PK
OE CUSTOMERS ACCOUNT_MGR_ID CUSTOMERS_ACCOUNT_MANAGER_FK HR EMPLOYEES EMPLOYEE_ID EMP_EMP_ID_PK
OE ORDERS SALES_REP_ID ORDERS_SALES_REP_FK HR EMPLOYEES EMPLOYEE_ID EMP_EMP_ID_PKSQL> /
Enter value for 1: JOB_ID_PK
old 23: AND pk.constraint_name = '&1'
new 23: AND pk.constraint_name = 'JOB_ID_PK'
FK_OWNER FK_TABLE FK_COLUMN FK_NAME PK_OWNER PK_TABLE PK_COLUMN PK_NAME
HR EMPLOYEES JOB_ID EMP_JOB_FK HR JOBS JOB_ID JOB_ID_PK
HR JOB_HISTORY JOB_ID JHIST_JOB_FK HR JOBS JOB_ID JOB_ID_PKSQL> /
Enter value for 1: DEPT_ID_PK
old 23: AND pk.constraint_name = '&1'
new 23: AND pk.constraint_name = 'DEPT_ID_PK'
FK_OWNER FK_TABLE FK_COLUMN FK_NAME PK_OWNER PK_TABLE PK_COLUMN PK_NAME
HR EMPLOYEES DEPARTMENT_ID EMP_DEPT_FK HR DEPARTMENTS DEPARTMENT_ID DEPT_ID_PK
HR JOB_HISTORY DEPARTMENT_ID JHIST_DEPT_FK HR DEPARTMENTS DEPARTMENT_ID DEPT_ID_PKSQL> /
Enter value for 1: JHIST_EMP_ID_ST_DATE_PK
old 23: AND pk.constraint_name = '&1'
new 23: AND pk.constraint_name = 'JHIST_EMP_ID_ST_DATE_PK'no rows selected
最后没有对应的外键,说明此主键只是当唯一索引用。
主外键约束的基本信息
SQL如下:
SELECT owner,constraint_name,constraint_type,table_name,status,delete_rule
FROM all_constraints
WHERE constraint_name = '&1';
示例输出如下:
Enter value for 1: EMP_DEPT_FK
old 8: WHERE constraint_name = '&1'
new 8: WHERE constraint_name = 'EMP_DEPT_FK'
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS DELETE_RULE
HR EMP_DEPT_FK R EMPLOYEES ENABLED NO ACTIONSQL> /
Enter value for 1: JOB_ID_PK
old 8: WHERE constraint_name = '&1'
new 8: WHERE constraint_name = 'JOB_ID_PK'
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS DELETE_RULE
HR JOB_ID_PK P JOBS ENABLEDSQL> /
Enter value for 1: EMP_EMP_ID_PK
old 8: WHERE constraint_name = '&1'
new 8: WHERE constraint_name = 'EMP_EMP_ID_PK'
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS DELETE_RULE
HR EMP_EMP_ID_PK P EMPLOYEES ENABLED
主外键约束列的信息
SQL如下:
SELECT owner,table_name,column_name,position
FROM all_cons_columns
WHERE constraint_name = '&1'
ORDER BY position;
示例输出如下:
Enter value for 1: DEPT_ID_PK
old 6: WHERE constraint_name = '&1'
new 6: WHERE constraint_name = 'DEPT_ID_PK'
OWNER TABLE_NAME COLUMN_NAME POSITION
HR DEPARTMENTS DEPARTMENT_ID 1SQL> /
Enter value for 1: JHIST_EMP_ID_ST_DATE_PK
old 6: WHERE constraint_name = '&1'
new 6: WHERE constraint_name = 'JHIST_EMP_ID_ST_DATE_PK'
OWNER TABLE_NAME COLUMN_NAME POSITION
HR JOB_HISTORY EMPLOYEE_ID 1
HR JOB_HISTORY START_DATE 2SQL> /
Enter value for 1: EMP_JOB_FK
old 6: WHERE constraint_name = '&1'
new 6: WHERE constraint_name = 'EMP_JOB_FK'
OWNER TABLE_NAME COLUMN_NAME POSITION
HR EMPLOYEES JOB_ID 1
外键参照的父表和列信息
SQL如下:
SELECT a.constraint_name AS fk_name,a.table_name AS child_table,a.column_name AS child_column,c.table_name AS parent_table,c.column_name AS parent_column
FROM all_cons_columns a
JOIN all_constraints bON a.owner = b.ownerAND a.constraint_name = b.constraint_name
JOIN all_cons_columns cON b.r_owner = c.ownerAND b.r_constraint_name = c.constraint_nameAND a.position = c.position
WHERE a.constraint_name = '&1';
示例输出如下:
Enter value for 1: JHIST_EMP_FK
old 14: WHERE a.constraint_name = '&1'
new 14: WHERE a.constraint_name = 'JHIST_EMP_FK'
FK_NAME CHILD_TABLE CHILD_COLUMN PARENT_TABLE PARENT_COLUMN
JHIST_EMP_FK JOB_HISTORY EMPLOYEE_ID EMPLOYEES EMPLOYEE_IDSQL> /
Enter value for 1: JHIST_DEPT_FK
old 14: WHERE a.constraint_name = '&1'
new 14: WHERE a.constraint_name = 'JHIST_DEPT_FK'
FK_NAME CHILD_TABLE CHILD_COLUMN PARENT_TABLE PARENT_COLUMN
JHIST_DEPT_FK JOB_HISTORY DEPARTMENT_ID DEPARTMENTS DEPARTMENT_IDSQL> /
Enter value for 1: JHIST_JOB_FK
old 14: WHERE a.constraint_name = '&1'
new 14: WHERE a.constraint_name = 'JHIST_JOB_FK'
FK_NAME CHILD_TABLE CHILD_COLUMN PARENT_TABLE PARENT_COLUMN
JHIST_JOB_FK JOB_HISTORY JOB_ID JOBS JOB_IDSQL> /
Enter value for 1: DEPT_MGR_FK
old 14: WHERE a.constraint_name = '&1'
new 14: WHERE a.constraint_name = 'DEPT_MGR_FK'
FK_NAME CHILD_TABLE CHILD_COLUMN PARENT_TABLE PARENT_COLUMN
DEPT_MGR_FK DEPARTMENTS MANAGER_ID EMPLOYEES EMPLOYEE_IDSQL> /
Enter value for 1: DEPT_LOC_FK
old 14: WHERE a.constraint_name = '&1'
new 14: WHERE a.constraint_name = 'DEPT_LOC_FK'
FK_NAME CHILD_TABLE CHILD_COLUMN PARENT_TABLE PARENT_COLUMN
DEPT_LOC_FK DEPARTMENTS LOCATION_ID LOCATIONS LOCATION_ID