我有一种情况,我需要通过SAS在Oracle中插入记录。 该表包含序列,因此要插入每条记录,我需要首先连接到Oracle并获取序列(nextval选项)。
我想减少此连接时间(推送1k条记录,连接1k次)。
另一个问题是,我不能简单地读取最大序列,以后再根据需要推入的记录数来更改序列,因为存在并发其他用户从其他系统推入数据。
所以在这里我需要帮助来禁用序列吗?而不是锁定表本身。
答案 0 :(得分:1)
好吧,我认为您不能禁用。您可以做的是创建一个数据库触发器,该触发器将注意插入其值。这是一个示例:
SQL> create table test (id number, col varchar2(20));
Table created.
SQL> create sequence seq_test;
Sequence created.
SQL> create or replace trigger trg_bi_test
2 before insert on test
3 for each row
4 begin
5 :new.id := nvl(:new.id, seq_test.nextval);
6 end;
7 /
Trigger created.
SQL> insert into test (col) values ('Little');
1 row created.
SQL> insert into test (col) values ('Foot');
1 row created.
SQL> select * from test;
ID COL
---------- --------------------
1 Little
2 Foot
SQL>
如您所见,您不必首先获取其值,数据库会照顾好它。请注意,如果您加载大量数据,性能可能会受到影响,因为触发器将针对插入的每一行触发。
对于使用“旧”方法(您目前拥有的用户)的用户,没有任何变化:
SQL> insert into test (id, col) values (seq_test.nextval, 'Stack');
1 row created.
SQL> select * from test;
ID COL
---------- --------------------
3 Stack
1 Little
2 Foot
SQL>
看看是否有帮助。
答案 1 :(得分:1)
如果只关心推送到数据库,则不需要来获取序列nextval
。只需在您的INSERT
语句中使用它即可:
CREATE TABLE vaibhav (
id NUMBER PRIMARY KEY,
data VARCHAR(100)
);
CREATE SEQUENCE vaibhav_seq;
INSERT INTO vaibhav(id, data)
VALUES (vaibhav_seq.nextval, 'foo');
INSERT INTO vaibhav(id, data)
VALUES (vaibhav_seq.nextval, 'bar');
SELECT id, data FROM vaibhav;
ID DATA
---- ----------
1 foo
2 bar
答案 2 :(得分:0)
如果知道N,即需要插入的SAS中的记录数,则可以执行传递查询,以从序列中获取N nextval值。
%let N_SEQ_NEEDED = 1000;
Proc SQL;
connect to oracle …;
create table work.sequence_numbers as select * from connection to oracle (
SELECT
ROWNUM n,
THE_NEEDED_SEQUENCE.nextval sequence_value
FROM (
SELECT 1 arbitrary_alias
FROM dual
CONNECT BY LEVEL <= &N_SEQ_NEEDED
)
);
来自http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques的CONNECT BY技术
不能保证N个nextval值的顺序性质-您只需要知道它们是唯一的,就永远不会在以后的nextval检索中重复。
合并或更新SAS数据集,将检索到的sequence_value分配给数据集的sequence列,然后通过SAS代码对Oracle执行INSERT。
答案 3 :(得分:0)
只需在单个查询中获取所有1000 NEXTVAL
,这应该很快。
CREATE SEQUENCE vaibhav_seq;
WITH t(n) AS (
SELECT 1 FROM DUAL
UNION ALL
SELECT n + 1 FROM t
WHERE n < 1000)
SELECT vaibhav_seq.NEXTVAL FROM t;
然后可以将其与INSERT
语句一起使用。