我又改了,还不行。
declare
myYear Varchar(10);
myYearCount NUMBER(10);
BEGIN
select to_char(sysdate,'yyyy') into myYear from dual;
select count(id) into myYearCount from foo where id like myYear+'%';
IF myYearCount<1 then
drop sequence foo_seq;
CREATE SEQUENCE foo_seq INCREMENT BY 1 START WITH 1
MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE
NOCACHE NOORDER;
END IF;
SELECT to_char(sysdate,'yyyy')||'-'||substr(to_char(foo_seq.nextval+10000),2,4) into :new.id from dual;
END;
declare
myYear Varchar(10);
myYearCount NUMBER(10);
BEGIN
select to_char(sysdate,'yyyy') into myYear from dual;
select count(id) into myYearCount from foo where id like myYear+'%';
IF myYearCount<1 then
drop sequence foo_seq;
CREATE SEQUENCE foo_seq INCREMENT BY 1 START WITH 1
MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE
NOCACHE NOORDER;
END IF;
SELECT to_char(sysdate,'yyyy')||'-'||substr(to_char(foo_seq.nextval+10000),2,4) into :new.id from dual;
END;
解决方案 »
- 一对多关系查询问题,在线等
- 如何把一个查询的结果集中的某些字段值拼成字符串,查询语句中的字段名还需使用变量
- 有谁对ORACLE的用户表和日志文件的结构比较清楚一些?
- rollup 的汇总行和下面的总和不相等 是什么原因呢???
- toad for Oracle
- SYBASE数据库中的时间字段是带毫秒信息的,怎样把这些信息存到ORACLE的时间字段中?
- 要实现分页显示,请问如何每次查询一定数量的记录
- 我用Oracle的企业管理器备份数据时,为什么总是提示:"ORA-01031: 权限不足"?
- odbc连接对话框在程序运行过程中的出现 是网络不稳定所谓的闪断的原因吗 哪位碰到过类似问题 谢谢excepiton 错误代码为 im006
- oracle存储过程可以导出Excel吗
- !!!有问题!ORACLE9I 一个简单表,数据量在1000万以上
- godblessu(上帝保佑)接分,今天这个网站不知道怎么了,贼慢
id varchar(9) primary key, --字符型
data varchar2(100)
); create sequence foo_seq
start with 1 increment by 1 maxvalue 9999; create or replace trigger bifer_foo_id_pk
before insert
on foo
for each row begin
/*
select count(id) into myYearCount from foo ;
if myYearCount<1 then begin
execute immediate ' drop sequence foo_seq';
execute immediate 'CREATE SEQUENCE foo_seq INCREMENT BY 1 START WITH 1
MAXVALUE 9999 MINVALUE 1 NOCYCLE
NOCACHE NOORDER ';
end;
end IF;
*/ 不能删除序列,会报错的。不要用在trigger种。
select to_char(sysdate,'yyyy')||'-'||substr(to_char(foo_seq.nextval+10000),2,4) into :new.id
from dual;
end;
/
--调试
execute immediate ' drop sequence foo_seq';
只能自己手动删除,创建。
那么象我这样的字增字段,该如何实现呢?
难道每年刚开始的时候,我都主动去将 sequence 删除?这太难了
myYear Varchar(10);
myYearCount NUMBER(10);
BEGIN
select to_char(sysdate,'yyyy') into myYear from dual;
select count(id) into myYearCount from foo where id like myYear+'%';
IF myYearCount<1 then
drop sequence foo_seq;
CREATE SEQUENCE foo_seq INCREMENT BY 1 START WITH 1
MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE
NOCACHE NOORDER;
END IF;
SELECT to_char(sysdate,'yyyy')||'-'||substr(to_char(foo_seq.nextval+10000),2,4) into :new.id from dual;
END;这个是无名过程:new.id从何而来,触发器里是不能使用动态SQL语句
但为什么要写在 trigger中 这中一年就改一次seq的情况 可以考虑用job完成
---------------------------------------------
也不难呀!知识麻烦一点。
你其实直接用你的程序里面的那个Count的值,完全可替代你的sequence,
或者选择,MAX的那个(假如你的程序会删除里面的ID的话),
这样,就没有你碰到的问题。因为,你的ID前4位是年,中间一个横线,最后的4位,用数据库里面最大的那个加1就好了,我的理解有错误吗?
1. 建序列:create sequence s1 start with 1 increment by 1
2. insert into t1(col) values('A' ||lpad(to_char(s1.nextval),10,'0'));
commit;
那第二年年初开工的时候,我必须还是要到每个用户那里去重建sequence :)同意 wupangzi(无本之木) 的意见!那么能不能换一个思路:建一个job,让他在每年1月1日0时0分,重建sequence。这样可以吗?
这个问题的关键点在于如何在每到一年,将sequence的值复位。所以可将sequence建成circle,每年的第一次条件触发后,用循环将sequence的值达到最大值,最后到1。这样做可以保证理论上的要求达到了。
但是缺点也很明显,首先很笨!每次想到要让这个sequence不停的加1到最大,只是为了将其变成1,就觉得运行此程序的计算机一定会狂骂编程的人(嘿嘿,程序不是我编的哟);当然,最重要的原因是如果sequence的最大值很大的话,每年第一次的运算时间会很长。唉,每年都要扮处女。不过还好,只有四位数,破瓜之痛应该能忍。
呵呵,忍不忍,就看楼主你了。
declare
myYear Varchar(10);
myYearCount NUMBER(10);
BEGIN
select to_char(sysdate,'yyyy') into myYear from dual;
select count(id) into myYearCount from foo where id like myYear+'%';
:new.id=to_char(sysdate,'yyyy')||'-'||lpad(to_char(myYearCount+1),4,'0');
commit;
END;
CREATE SEQUENCE foo_seq INCREMENT BY 1 START WITH 1
MAXVALUE 9999 MINVALUE 1 CYCLE 触发器的修改: --变量定义中加入一个数字变量
seq_val number ; --将原触发器中的if到end if修改如下
if myYearCount<1 then
select foo_seq.currval into seq_val from dual;
--以下循环执行完以后,foo_seq.curr等于9999,下次取foo_seq.nextval就等于1
while seq_val<9999 loop
select foo_seq.nextval into seq_val from dual;
end loop;
end IF;
如果现在数据库里面已经有记录了,比如已经有2004-0120。
而我建的squence是从1开始的,那么我
在sql plus窗口中做一个什么操作,可以让squence当前的数值达到121呢?
万分感谢,我这就试一试。
declare
myYear Varchar(10);
myYearCount NUMBER(10);
seq_val NUMBER(5);
BEGIN
select (to_char(sysdate,'yyyymm')||'%') into myYear from dual;
select count(HIRENO) into myYearCount from CARHIRE where HIRENO like myYear;
if myYearCount<1 then
select CARHIRE_SQUENCE.currval into seq_val from dual;
--以下循环执行完以后,MY_seq.curr等于9999,下次取MY_seq.nextval就等于1
while seq_val<9999 loop
select CARHIRE_SQUENCE.nextval into seq_val from dual;
end loop;
end IF;
select to_char(sysdate,'yyyymm')||'-'||lpad(to_char(CARHIRE_SQUENCE.nextval),4,'0') into :new.HIRENO from dual;
END;
也有carhire表。可插入纪录时还是出错了。
SQL> insert into carhire(carno,carrysum)values('xin-24280',12.34);
insert into carhire(carno,carrysum)values('xin-24280',12.34)
*
ERROR 位于第 1 行:
ORA-08002: 序列CARHIRE_SQUENCE.CURRVAL 尚未在此进程中定义
ORA-06512: 在"JAMIS.T_INSERT_CARHIRE", line 9
ORA-04088: 触发器 'JAMIS.T_INSERT_CARHIRE' 执行过程中出错急,在线等 胖子等诸位高人解答
我刚调试过了,只要手动执行
select carhire_squence.nextval from dual
一次就可以了。
至于你的程序,两种方法:
1 修改一下来防止第一次运行时候的问题
2 不用修改,在建立carhire_squence时候执行一下那条语句,让currval有值就可以不用管了。
我帮你找了一个可以较好解决这个问题的贴子
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=160143
其实思路我和他的差不多,不过我的真的只能算权宜之计,建议用他的方法,虽然要涉及到权限和动态sql,不过有他代码了,相信对你来说不会太麻烦。
我试了一下,好像没问题declare
myYear Varchar(10);
myYearCount NUMBER(10);
seq_val NUMBER(5);
BEGIN
select (to_char(sysdate,'yyyymm')||'%') into myYear from dual;
select count(HIRENO) into myYearCount from CARHIRE where HIRENO like myYear;
if myYearCount<1 then
select CARHIRE_SQUENCE.nextval into seq_val from dual;
--以下循环执行完以后,MY_seq.curr等于9999,下次取MY_seq.nextval就等于1
while seq_val<9999 loop
select CARHIRE_SQUENCE.nextval into seq_val from dual;
end loop;
end IF;
select to_char(sysdate,'yyyymm')||'-'||lpad(to_char(CARHIRE_SQUENCE.nextval),4,'0') into :new.HIRENO from dual;
END;
你介绍的新方法,不简单,我还得好好看看,这句话是什么意思?
dbms_job.submit(jobno,'pro;',sysdate,'sysdate+17/24+1'); 谢谢了
select 121 into CARHIRE_SQUENCE.currval from dual;
这样来改变squence的当前值??????
2、支持!呵呵,原来同一个问题解决方法倒蛮多的,我以前只会胖子老兄的;学习ing ……
理论上没有问题,但如果currval=9999则会让程序多执行9999的空循环,不划算。dbms_job.submit(jobno,'pro;',sysdate,'sysdate+17/24+1');
这是创建job的语句,用来定时触发执行名为pro的过程改变序列当前值的方法我给你推荐的文档里面有
alter sequence sqtest increment by 4
你这里要用则要涉及动态SQL,你仔细研究一下那篇文章吧,对你的问题很有帮助的