我的InterBase解决方案,请参考
/* Table MATERIAL_ID */
CREATE TABLE MATERIAL_ID (
MAT_ID VARCHAR(15) NOT NULL,
MAT_NAME VARCHAR(40) NOT NULL,
MAT_SEED SMALLINT DEFAULT 0 NOT NULL,
MAT_FMT VARCHAR(8),
MAT_SUB1 VARCHAR(5) NOT NULL,
MAT_SUB2 VARCHAR(5),
MAT_SUB3 VARCHAR(5),
MAT_SUB4 VARCHAR(5),
MAT_NOTE VARCHAR(256)
)
/* Procedure GET_MAT_ID */
CREATE PROCEDURE GET_MAT_ID (
NMAT_SUB1 CHAR(2),
NMAT_SUB2 CHAR(2),
NMAT_SUB3 CHAR(2),
NMAT_SUB4 CHAR(2)
) RETURNS (
NMAT_ID INTEGER,
NMAT_SUB INTEGER
) AS
DECLARE VARIABLE seed integer;
DECLARE VARIABLE lastseed integer;
BEGIN
nmat_id=0;
nmat_sub=0;
lastseed=0;
if (nmat_sub1 is null or nmat_sub1='00')then
begin
nmat_sub=1;
for select cast(mat_sub1 as integer) from material_id
where mat_sub1<>'99' and
mat_sub2 is null and
mat_sub3 is null and
mat_sub4 is null
order by mat_sub1 asc
into :seed
do
begin
if((seed-lastseed)>1)then
begin
nmat_id=lastseed+1;
if(nmat_id>=99 )then exception matclassfull;
exit;
end
lastseed=seed;
end
nmat_id=lastseed+1;
if(nmat_id>99 )then exception matclassfull;
exit;
end
else
if (nmat_sub2 is null or nmat_sub2='00')then
begin
nmat_sub=2;
for
select cast(mat_sub2 as integer) from material_id
where mat_sub1=:nmat_sub1 and
mat_sub2 <>'99' and
mat_sub3 is null and
mat_sub4 is null
order by mat_sub2 asc
into :seed
do
begin
if((seed-lastseed)>1)then
begin
nmat_id=lastseed+1;
if(nmat_id>=99 )then exception matclassfull;
exit;
end
lastseed=seed;
end
nmat_id=lastseed+1;
if(nmat_id>99 )then exception matclassfull;
exit;
end
else
if (nmat_sub3 is null or nmat_sub3='00')then
begin
nmat_sub=3;
for
select cast(mat_sub3 as integer) from material_id
where mat_sub1=:nmat_sub1 and
mat_sub2=:nmat_sub2 and
mat_sub3<>'99' and
mat_sub4 is null
order by mat_sub3 asc
into :seed
do
begin
if((seed-lastseed)>1)then
begin
nmat_id=lastseed+1;
if(nmat_id>=99 )then exception matclassfull;
exit;
end
lastseed=seed;
end
nmat_id=lastseed+1;
if(nmat_id>99 )then exception matclassfull;
exit;
end
else
if (nmat_sub4 is null or nmat_sub4='00')then
begin
nmat_sub=4;
for
select cast(mat_sub4 as integer) from material_id
where mat_sub1=:nmat_sub1 and
mat_sub2=:nmat_sub2 and
mat_sub3=:nmat_sub3 and
mat_sub4<>'999'
order by mat_sub4 asc
into :seed
do
begin
if((seed-lastseed)>1)then
begin
nmat_id=lastseed+1;
if(nmat_id>=999 )then exception matclassfull;
exit;
end
lastseed=seed;
end
nmat_id=lastseed+1;
if(nmat_id>999 )then exception matclassfull;
exit;
end
END
/* Trigger MATERIAL_IDTRGINS */
CREATE TRIGGER MATERIAL_IDTRGINS FOR MATERIAL_ID BEFORE INSERT POSITION 0 AS
DECLARE VARIABLE nmat_id integer;
DECLARE VARIABLE nmat_sub integer;
DECLARE VARIABLE nmatstr varchar(3);
BEGIN
if(new.mat_id='00')then
begin
EXECUTE PROCEDURE get_mat_id
new.mat_sub1,new.mat_sub2,
new.mat_sub3,new.mat_sub4
RETURNING_VALUES :nmat_id,:nmat_sub;
if(nmat_sub=4)then
begin
if(nmat_id<=9)then
nmatstr='00'||cast(nmat_id as char(1));
else if(nmat_id<=99)then
nmatstr='0'||cast(nmat_id as char(2));
else if(nmat_id<=999)then
nmatstr=cast(nmat_id as char(3));
else
exception idtoolarge;
end
else
begin
if(nmat_id<=9)then
nmatstr='0'||cast(nmat_id as char(1));
else if(nmat_id<=99)then
nmatstr=cast(nmat_id as char(2));
else
exception idtoolarge;
end
if(nmat_sub=1)then
begin
new.mat_sub1=nmatstr;
new.mat_id=new.mat_sub1;
end
if(nmat_sub=2)then
begin
new.mat_sub2=nmatstr;
new.mat_id=new.mat_sub1||new.mat_sub2;
end
if(nmat_sub=3)then
begin
new.mat_sub3=nmatstr;
new.mat_id=new.mat_sub1||new.mat_sub2||new.mat_sub3;
end
if(nmat_sub=4)then
begin
new.mat_sub4=nmatstr;
new.mat_id=new.mat_sub1||new.mat_sub2||new.mat_sub3||new.mat_sub4;
end
end
END