英文:
How to load a hierarchical table using a sequence in Oracle SQL
问题
如果我有一个层次表:TREE(ID,PARENT_ID,NAME)
如何在SQL中使用序列加载它?
在PLSQL中,我们可以使用变量等,但我想知道是否可以在SQL中完成。
这显然不起作用,它在第2行失败,因为ID = PARENT_ID,而且我有一个检查约束来防止这种情况。
insert into tree (TREE_SEQ.NEXTVAL, NULL, 'root');
insert into tree (TREE_SEQ.CURRVAL, TREE_SEQ.NEXTVAL, 'branch');
这个方法可以工作,但我对并发性有一些担忧。
它还假设序列是使用INCREMENT BY 1
定义的。
insert into tree (TREE_SEQ.NEXTVAL, NULL, 'root');
insert into tree (TREE_SEQ.NEXTVAL, TREE_SEQ.CURRVAL - 1, 'branch');
英文:
If I have a hierarchical table : TREE (ID, PARENT_ID, NAME)
How can this be loaded in sql using a sequence?
In PLSQL we could use variables etc. but I'm wondering if it can be done in SQL.
This obviously won't work, it fails on row 2 because ID = PARENT_ID and I have a check constraint preventing it.
insert into tree (TREE_SEQ.NEXTVAL, NULL, 'root');
insert into tree (TREE_SEQ.CURRVAL, TREE_SEQ.NEXTVAL, 'branch');
This works, but I have concerns about concurrency.
It also assumes that the sequence is defined with INCREMENT BY 1
insert into tree (TREE_SEQ.NEXTVAL, NULL, 'root');
insert into tree (TREE_SEQ.NEXTVAL, TREE_SEQ.CURRVAL - 1, 'branch');
答案1
得分: 1
你应该只使用PL/SQL:
DECLARE
v_id tree.id%TYPE;
BEGIN
INSERT INTO tree (ID, PARENT_ID, NAME)
VALUES (TREE_SEQ.NEXTVAL, NULL, 'root')
RETURNING id INTO v_id;
INSERT INTO tree (ID, PARENT_ID, NAME)
VALUES (TREE_SEQ.NEXTVAL, v_id, 'branch');
END;
/
然后,根据以下设置:
CREATE TABLE TREE (
ID NUMBER PRIMARY KEY,
PARENT_ID REFERENCES tree(id),
NAME VARCHAR2(10)
);
CREATE SEQUENCE tree_seq;
然后在PL/SQL块之后,表包含以下内容:
ID | PARENT_ID | NAME |
---|---|---|
1 | null | root |
2 | 1 | branch |
然而,如果你创建一个包装序列的函数:
CREATE FUNCTION get_tree_sequence RETURN TREE.ID%TYPE
IS
BEGIN
RETURN TREE_SEQ.NEXTVAL;
END;
/
然后你可以在SQL语句中使用它:
INSERT INTO tree (ID, PARENT_ID, NAME)
SELECT id,
LAG(id) OVER (ORDER BY ROWNUM),
CASE ROWNUM WHEN 1 THEN 'root' ELSE 'branch' END
FROM (
SELECT get_tree_sequence() AS id
FROM DUAL
CONNECT BY LEVEL <= 2
);
然后表现在包含以下内容:
ID | PARENT_ID | NAME |
---|---|---|
1 | null | root |
2 | 1 | branch |
3 | null | root |
4 | 3 | branch |
英文:
You ought to just use PL/SQL:
DECLARE
v_id tree.id%TYPE;
BEGIN
INSERT INTO tree (ID, PARENT_ID, NAME)
VALUES (TREE_SEQ.NEXTVAL, NULL, 'root')
RETURNING id INTO v_id;
INSERT INTO tree (ID, PARENT_ID, NAME)
VALUES (TREE_SEQ.NEXTVAL, v_id, 'branch');
END;
/
Which, given the setup:
CREATE TABLE TREE (
ID NUMBER PRIMARY KEY,
PARENT_ID REFERENCES tree(id),
NAME VARCHAR2(10)
);
CREATE SEQUENCE tree_seq;
Then after the PL/SQL block, the table contains:
ID | PARENT_ID | NAME |
---|---|---|
1 | null | root |
2 | 1 | branch |
However, if you create a function to wrap the sequence:
CREATE FUNCTION get_tree_sequence RETURN TREE.ID%TYPE
IS
BEGIN
RETURN TREE_SEQ.NEXTVAL;
END;
/
Then you can use it in an SQL statement:
INSERT INTO tree (ID, PARENT_ID, NAME)
SELECT id,
LAG(id) OVER (ORDER BY ROWNUM),
CASE ROWNUM WHEN 1 THEN 'root' ELSE 'branch' END
FROM (
SELECT get_tree_sequence() AS id
FROM DUAL
CONNECT BY LEVEL <= 2
);
Then the table now contains:
ID | PARENT_ID | NAME |
---|---|---|
1 | null | root |
2 | 1 | branch |
3 | null | root |
4 | 3 | branch |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论