我使用此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
/
你能帮我解决这个问题吗?
答案 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
。