Jadi masalahnya adalah, harus ada pengguna di puncak hierarki, pengguna yang tidak memiliki manajer (editor dalam contoh Anda). Itulah sebabnya solusi klasik untuk struktur semacam ini adalah mengizinkan nilai nol. Anda mengakui ini di paragraf penutup Anda:
Penendangnya adalah, jika pengguna pertama tidak memiliki CREATOR atau EDITOR maka tidak ada "sementara":Anda harus membuang batasan wajib. Jika Anda melakukan ini, masalah dengan batasan kunci asing rekursif akan hilang.
Alternatifnya adalah dengan memperkenalkan apa yang disebut Aristoteles sebagai Penggerak Utama, Pengguna yang Penciptanya adalah dirinya sendiri. Diberikan tabel ini:
create table t72
( userid number not null
, creator number not null
, editor number not null
, constraint t72_pk primary key (userid)
, constraint t72_cr_fk foreign key (creator)
references t72 (userid)
, constraint t72_ed_fk foreign key (editor)
references t72 (userid)
)
/
cukup mudah untuk membuat pengguna seperti itu:
SQL> insert into t72 values (1,1,1)
2 /
1 row created.
SQL> commit;
Commit complete.
SQL>
Jadi mengapa ini bukan solusi kanonik. Ini mengarah ke model data yang sedikit aneh yang dapat membuat kekacauan dengan kueri hierarkis setelah kami menambahkan beberapa pengguna lagi.
SQL> select lpad(' ', level-1)|| u.userid as userid
2 , u.name
3 , u.editor
4 from t72 u
5 connect by
6 prior userid = editor
7 start with userid=1
8 /
ERROR:
ORA-01436: CONNECT BY loop in user data
no rows selected
SQL>
Pada dasarnya database tidak suka USERID menjadi editornya sendiri. Namun, ada solusinya, yaitu NOCYCLE
kata kunci (diperkenalkan dengan 10g). Ini memberitahu database untuk mengabaikan referensi melingkar dalam hierarki:
SQL> select lpad(' ', level-1)|| u.userid as userid
2 , u.name
3 , u.editor
4 from t72 u
5 connect by nocycle
6 prior userid = editor
7 start with userid=1
8 /
USERID NAME EDITOR
---------- ---------- ----------
1 ONE 1
2 TWO 1
3 THREE 2
4 FOUR 2
5 FIVE 2
6 SIX 2
7 SEVEN 6
7 rows selected.
SQL>
Di sini tidak masalah karena datanya masih hierarkis dengan benar. Tapi apa jadinya jika kita melakukan ini:
SQL> update t72 set editor = 7
2 where userid = 1
3 /
1 row updated.
SQL>
Kami kehilangan hubungan (1 -> 7). Kita dapat menggunakan pseudo-kolom CONNECT_BY_ISNOCYCLE untuk melihat baris mana yang bersepeda.
SQL> select lpad(' ', level-1)|| u.userid as userid
2 , u.name
3 , u.editor
4 , connect_by_iscycle
5 from t72 u
6 connect by nocycle
7 prior userid = editor
8 start with userid=1
9 /
USERID NAME EDITOR CONNECT_BY_ISCYCLE
---------- ---------- ---------- ------------------
1 ONE 7 0
2 TWO 1 0
3 THREE 2 0
4 FOUR 2 0
5 FIVE 2 0
6 SIX 2 0
7 SEVEN 6 1
7 rows selected.
SQL>
Oracle memiliki banyak fungsi tambahan untuk mempermudah bekerja dengan data hierarkis dalam SQL murni. Itu semua ada di dokumentasi. Cari tahu lebih lanjut .