Re: ORACLE-SQL : Sequence Problem (Need SQL GURUS)
Date: Thu, 10 Sep 1998 06:57:19 +0200
Message-ID: <6t7m54$8f3$1_at_newton.a2000.nl>
> The only way I know of "resetting" a sequence is to kill it and
recreate
>it.
You can use alter to set the increment_by to a negative value. See below.
> I would suggest using the 'for counter in 1 .. <p_limit> loop'
This can take a long time...
>>How can I write the code (SQL or PL/SQL or SQL*PLUS)that will increase the >>sequence value until it match the value of other parameter value and reset >>its value back to 1.
Can't you set max_value when you define the trigger?
I do not really understand the problem, but below is a procedure that will set any sequence to a desired value. This is not the final version I once used -- e.g. you'll have to debug and test it yourself.
Arjan.
function exec_ddl( p_statement in varchar2)
return integer
is
l_cursorid integer;
l_rowcount integer;
begin
l_rowcount := null;
--
l_cursorid := dbms_sql.open_cursor;
dbms_sql.parse( l_cursorid, p_statement, dbms_sql.native);
l_rowcount := dbms_sql.execute( l_cursorid);
dbms_sql.close_cursor( l_cursorid);
--
if l_rowcount is null then
raise_application_error( -20000, 'Error executing ' || p_statement);
end if;
--
return l_rowcount;
exception
when others then
if dbms_sql.is_open( l_cursorid) then dbms_sql.close_cursor( l_cursorid); end if; raise;
end exec_ddl;
-- -- ----------------------------------------------------------------- --
procedure alter_session_commit( p_change in varchar2) is l_cursor integer;
l_aarows integer;
begin
l_cursor := dbms_sql.open_cursor;
dbms_sql.parse ( l_cursor, 'alter session '|| p_change
|| ' commit in procedure', dbms_sql.v7);l_aarows := dbms_sql.execute (l_cursor); dbms_sql.close_cursor (l_cursor);
exception
when others then
if dbms_sql.is_open (l_cursor) then dbms_sql.close_cursor (l_cursor); end if; raise;
end alter_session_commit;
-- -- ----------------------------------------------------------------- -- -- The column last_number gives the last value of the sequence -- that is stored somewhere in Oracle. This value is not necessarily -- the value that would be returned by currval. Nor wil nextval return -- last_number + increment... -- If the cache_size is 20, and currval is 1001, then last_number -- yeilds 1020. As soon as nextvall returns 1020, last_number will -- be set to 1040. Therefore, the column last_number only tells us -- what the last issued sequence number was when cache_size = 1. -- In all other case, nextval need to be used to get a new value. -- -- ----------------------------------------------------------------- -- function set_seq( p_seq_name in varchar2 , p_newval in integer ) return integer
is
--
r_useq user_sequences%rowtype; l_increment_by user_sequences.increment_by%type; l_newval user_sequences.last_number%type; l_lastval user_sequences.last_number%type; l_nextval user_sequences.last_number%type; l_currval user_sequences.last_number%type; l_succes binary_integer;
--
l_meld varchar2(100);
--
begin
--
l_newval := p_newval;
--
begin
select * into r_useq from user_sequences where sequence_name = upper( p_seq_name); exception when no_data_found then raise_application_error( -20000, 'Sequence ' || p_seq_name || ' does not exist'); return null;
end;
--
if l_newval < r_useq.min_value then
l_newval := r_useq.min_value;
end if;
--
if l_newval > r_useq.max_value then
l_newval := r_useq.max_value;
end if;
--
if r_useq.cache_size = 1 then
l_currval := r_useq.last_number; l_lastval := l_currval; if l_currval = l_newval then return l_currval; end if; else -- l_currval := exec_query( 'select ' || p_seq_name || '.nextval from sys.dual'); -- l_lastval := l_currval - r_useq.increment_by; if l_currval = l_newval then return l_currval; elsif l_currval is null then return null; -- in fact, error already raised by exec_query end if;
end if;
--
- l_currval != l_newval
--
- l_newval r_useq_increment_by l_lastval l_currval l_increment_by
- -------- ------------------- --------- --------- --------------
- 100 1 5 6 94
- 100 1 123 124 -24
- 100 10 50 60 40
--
l_increment_by := l_newval - l_currval;
--
alter_session_commit( 'ENABLE');
--
--
l_succes := exec_ddl( 'alter sequence ' || p_seq_name || ' increment by ' || to_char( l_increment_by));
--
if l_succes is null then return null; -- in fact, error already raised by exec_ddl end if;
--
- Make l_currval = l_newval
--
l_currval := exec_query( 'select ' || p_seq_name || '.nextval from sys.dual');
--
--
l_succes := exec_ddl( 'alter sequence ' || p_seq_name || ' increment by ' || to_char( r_useq.increment_by));
--
if l_succes is null then return null; -- in fact, error already raised by exec_ddl end if;
--
alter_session_commit( 'DISABLE');
--
return l_currval; end set_seq; --- ----------------------------------------------------------------- -- procedure set_seq( p_seq_name in varchar2 , p_newval in integer) is l_dummy binary_integer; begin l_dummy := set_seq( p_seq_name, p_newval); end; -- -- end of script