java.sql.SQLSyntaxErrorException:ORA-02287:此处不允许使用序列号

时间:2015-08-29 22:32:40

标签: jquery oracle oracle11g

我使用此SQL查询将值插入Oracle:

  character*80 :: inline
  integer      :: i, imod, stat

  open(1,file='infile')
  open(2,file='outfile',status='unknown')

  i = 0
  do
     i = i + 1
     read(1,'(80a)',iostat=stat) inline
     if (stat/=0) then !EOF reached
        exit
     end if 

     imod = mod(i-1,9) + 1
     if (imod>=7 .and. imod<=9) then
        write(2,*) inline
     end if
  end do

这是表格的结构:

INSERT INTO SESSIONS (
  SESSIONID,
  TYPE,
  ACTIVITY_START,
  ACTIVITY_END,
  ACTIVITY,
  USERNAME,
  IP_ADDRESS,
  LOGIN_TIME,
  LOGOUT_TIME)
select SESSION_ID_SEQ.nextval, null, null, null, ?, ?, ?, sysdate, null
FROM SESSIONS
having COUNT(*) < 50

我使用sequence为每个新会话记录生成唯一ID。 但是当我运行代码时出现错误:

CREATE TABLE SESSIONS(
  SESSIONID VARCHAR2(30 ) NOT NULL,
  TYPE VARCHAR2(30 ),
  ACTIVITY_START DATE,
  ACTIVITY_END DATE,
  ACTIVITY CLOB,
  USERNAME VARCHAR2(30 ),
  IP_ADDRESS VARCHAR2(30 ),
  LOGIN_TIME DATE,
  LOGOUT_TIME DATE
)
/

CREATE SEQUENCE SESSION_ID_SEQ
 INCREMENT BY 1
 MAXVALUE 9999999999999999999999999999
 NOMINVALUE
 CACHE 20
/

你能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

由于您需要插入行以使SESSIONS表行数最多为50,因此您需要的是计算50减去SESSIONS中的行数。要计算,您可以使用Oracle CONNECT BY的hack,它主要与分层查询相关联,但还有很多其他用途。例如,尝试此查询,它将返回编号为1到50的50行:

SELECT ROWNUM
FROM DUAL
CONNECT BY ROWNUM <= 50;

如果您的SESSION表中已有30行,则此查询将返回20行:

SELECT ROWNUM
FROM DUAL
CONNECT BY ROWNUM <= 50 - (
  SELECT COUNT(*) FROM SESSIONS
);

顺便说一句,虽然ROWNUM的查询需要CONNECT BY,但它并不需要SELECT值;这只是为了演示目的。

据我了解,您的查询看起来像这样:

INSERT INTO SESSIONS (
  SESSIONID,
  TYPE,
  ACTIVITY_START,
  ACTIVITY_END,
  ACTIVITY,
  USERNAME,
  IP_ADDRESS,
  LOGIN_TIME,
  LOGOUT_TIME)
select SESSION_ID_SEQ.nextval, null, null, null, ?, ?, ?, sysdate, null
FROM DUAL
CONNECT BY ROWNUM <= 50 - (
  SELECT COUNT(*)
  FROM SESSIONS
);

由于其中四列将为null(并且由于四列中没有一列定义了您用null覆盖的DEFAULT值,因此可以通过省略列来缩短查询:

INSERT INTO SESSIONS (
  SESSIONID,
  ACTIVITY,
  USERNAME,
  IP_ADDRESS,
  LOGIN_TIME)
select SESSION_ID_SEQ.nextval, ?, ?, ?, sysdate
FROM DUAL
CONNECT BY ROWNUM <= 50 - (
  SELECT COUNT(*)
  FROM SESSIONS
);

最后,请注意,SYSDATE值对于您插入的每一行都是完全相同的。这是因为SYSDATE(和SYSTIMESTAMP)对于每个查询仅评估一次,并且在查询的持续时间内使用相同的值。即使您的查询运行了一个小时,每行也会有相同的SYSDATE