我有十好几个表有自增的需要,而且它们之间还会有关联,所以我要建一个表(例如表Y),存放其他表的表名、最大ID号,在其他表(例如A表)执行insert语句之前先执行这个存储过程,让存储过程把Y表里相关记录的值+1(记录A表里id最大值的那条记录),然后锁上住这条记录,不允许其他用户对这条记录的并发操作,然后取出+1后的值(是个number的值)插入到A表中或做其他操作,事务执行完后commit提交,其他人 才可对Y表这条记录update
我写不好,但是急用,也没有时间看书了,肯请大家帮助,帮我把这个存储过程完成,并且告诉我怎么调用,我使用 jsp + javabean
我想把这个存储过程应用到多个表,所以最理想的结果是传入表名、列名(id列的列名和具有唯一标识的一个列名),最后要返回一个最新插入的id值
如果不能应用到多个表,就请大家帮我写个对单个表操作的存储过程,传入列名,传出最新更新的id值,然后告诉我怎样调用
急用,谢谢大家!
12 个解决方案
#1
对了,我用的是oracle9i
#2
我朋友哪里有这个函数,我已经把帖子号给他了。
#3
下面是我自己写的:
table_maxid表结构:
----名称-----数据类型---大小---小数位---是否为空?----默认值
tablename----varchar2----30---------------------------------
maxid----------number----10--------0------------------------
建表后,先插入一条记录:
insert into table_maxid (tablename,maxid) values ('table1',0);
存储过程:testproc
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
调用:
execute testproc('table1');出错, 我就不会写了,呵呵,晕菜!!
感谢楼上,一定结贴!!!
table_maxid表结构:
----名称-----数据类型---大小---小数位---是否为空?----默认值
tablename----varchar2----30---------------------------------
maxid----------number----10--------0------------------------
建表后,先插入一条记录:
insert into table_maxid (tablename,maxid) values ('table1',0);
存储过程:testproc
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
调用:
execute testproc('table1');出错, 我就不会写了,呵呵,晕菜!!
感谢楼上,一定结贴!!!
#4
CREATE PROCEDURE PROC_AUTOID @IDName char(10),@IDString char(20) out as
begin
Declare @length char(20),@tempid char(20),@tempkind Char(2),@templength int
Declare @tempint int
Declare @yy char(2),@mm char(2),@dd char(2),@tempdate char(6)
Declare ID_cursor Cursor For Select lastid,idname,idkind,idlength From autoid Where idname=@IDName
Open ID_cursor
Fetch Next From ID_cursor into @length,@tempid,@tempkind,@templength
set @length=rtrim(@length)
If @@FETCH_STATUS = 0
begin
if @tempkind='1'
begin
set @yy=convert(char(2),right(year(getdate()),2))
set @mm=convert(char(2),month(getdate()))
if (len(@mm)=1)
set @mm='0'+@mm
set @dd=convert(char(2),day(getdate()))
if (len(@dd)=1)
set @dd='0'+@mm
set @tempdate=@yy+@mm+@dd
if @tempdate=left(@length,6)
begin
set @tempint=convert(int, right(rtrim(@length),4))
set @tempint= @tempint+1
set @IDString=@tempdate+left('0000',4-len(@tempint))+convert(char,@tempint)
end
else
begin
set @IDString=@tempdate+'0001'
end
end
if @tempkind='2'
begin
if @length=null
begin
set @IDString='0001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('0000',4-len(@tempint))+convert(char,@tempint)
end
end
If @tempkind='3'
begin
If (@length=null) or (isnumeric(@length)=0)
begin
set @IDString='000001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('000000',6-len(@tempint))+convert(char,@tempint)
end
end
end
close ID_cursor
deallocate ID_cursor
update autoid set lastid=@IDString where idname= @IDName
select lastid from autoid where idname= @IDName
--客户编号加前缀‘N’
if @IDName='khbh'
set @IDString='N'+@IDString
end
GO
麻烦吧
还得建表autoid
调用
public String executeProc(String IDName)
{
String returnstr,sqlstr,rsstr;
rs=null;
sqlstr = "{call PROC_AUTOID(?,?)}";
try
{
if (conn!=null)
{
conn.close();
}
conn = DriverManager.getConnection(sConnStr,UseName,PassWord);
CallableStatement stmt = conn.prepareCall(sqlstr);
stmt.setString(1,IDName);
stmt.registerOutParameter(2,Types.CHAR);
rs=stmt.executeQuery();
rs.next();
rsstr = rs.getString(1);
returnstr = stmt.getString(2);
rs.close();
stmt.close();
conn.close();
}
catch (Exception erproc)
{
return null;
}
return returnstr;
}
begin
Declare @length char(20),@tempid char(20),@tempkind Char(2),@templength int
Declare @tempint int
Declare @yy char(2),@mm char(2),@dd char(2),@tempdate char(6)
Declare ID_cursor Cursor For Select lastid,idname,idkind,idlength From autoid Where idname=@IDName
Open ID_cursor
Fetch Next From ID_cursor into @length,@tempid,@tempkind,@templength
set @length=rtrim(@length)
If @@FETCH_STATUS = 0
begin
if @tempkind='1'
begin
set @yy=convert(char(2),right(year(getdate()),2))
set @mm=convert(char(2),month(getdate()))
if (len(@mm)=1)
set @mm='0'+@mm
set @dd=convert(char(2),day(getdate()))
if (len(@dd)=1)
set @dd='0'+@mm
set @tempdate=@yy+@mm+@dd
if @tempdate=left(@length,6)
begin
set @tempint=convert(int, right(rtrim(@length),4))
set @tempint= @tempint+1
set @IDString=@tempdate+left('0000',4-len(@tempint))+convert(char,@tempint)
end
else
begin
set @IDString=@tempdate+'0001'
end
end
if @tempkind='2'
begin
if @length=null
begin
set @IDString='0001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('0000',4-len(@tempint))+convert(char,@tempint)
end
end
If @tempkind='3'
begin
If (@length=null) or (isnumeric(@length)=0)
begin
set @IDString='000001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('000000',6-len(@tempint))+convert(char,@tempint)
end
end
end
close ID_cursor
deallocate ID_cursor
update autoid set lastid=@IDString where idname= @IDName
select lastid from autoid where idname= @IDName
--客户编号加前缀‘N’
if @IDName='khbh'
set @IDString='N'+@IDString
end
GO
麻烦吧
还得建表autoid
调用
public String executeProc(String IDName)
{
String returnstr,sqlstr,rsstr;
rs=null;
sqlstr = "{call PROC_AUTOID(?,?)}";
try
{
if (conn!=null)
{
conn.close();
}
conn = DriverManager.getConnection(sConnStr,UseName,PassWord);
CallableStatement stmt = conn.prepareCall(sqlstr);
stmt.setString(1,IDName);
stmt.registerOutParameter(2,Types.CHAR);
rs=stmt.executeQuery();
rs.next();
rsstr = rs.getString(1);
returnstr = stmt.getString(2);
rs.close();
stmt.close();
conn.close();
}
catch (Exception erproc)
{
return null;
}
return returnstr;
}
#5
楼上,第一行返回下述错误:
行号= 1 列号= 29 错误文本= PLS-00103: 出现符号 "CREATE"在需要下列之一时: ( ; is with authid as cluster compress order using compiled wrapped external deterministic parallel_enable pipelined
这是什么意思啊?
行号= 1 列号= 29 错误文本= PLS-00103: 出现符号 "CREATE"在需要下列之一时: ( ; is with authid as cluster compress order using compiled wrapped external deterministic parallel_enable pipelined
这是什么意思啊?
#6
select ..for update;
#7
楼上的写法是sql server的t-sql语法,不适用于oracle。
不明白楼主为什么不用sequence,那简单很多啊
不明白楼主为什么不用sequence,那简单很多啊
#8
先执行+1操作
锁住记录:select col1 from tablename for update;
锁住记录:select col1 from tablename for update;
#9
to 弱水三千:不用序列是因为那一系列操作中一旦出错,就无法回滚,用存储过程就可以。如果你有好的方法,请告知,急啊
#10
不用序列,那只能你自己解决并发问题了,不是很容易的.
#11
如果我把存储过程写成这样:
存储过程名:testproc
内容:
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
比如里面有一条记录,
insert into table_maxid (tablename,maxid) values ('table1',0);
应怎么调用呢?
execute testproc('table1'...);
上面这行,有三个点的地方应怎么写呢?
请教!!
存储过程名:testproc
内容:
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
比如里面有一条记录,
insert into table_maxid (tablename,maxid) values ('table1',0);
应怎么调用呢?
execute testproc('table1'...);
上面这行,有三个点的地方应怎么写呢?
请教!!
#12
up一下,再不解决就结贴了!
#1
对了,我用的是oracle9i
#2
我朋友哪里有这个函数,我已经把帖子号给他了。
#3
下面是我自己写的:
table_maxid表结构:
----名称-----数据类型---大小---小数位---是否为空?----默认值
tablename----varchar2----30---------------------------------
maxid----------number----10--------0------------------------
建表后,先插入一条记录:
insert into table_maxid (tablename,maxid) values ('table1',0);
存储过程:testproc
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
调用:
execute testproc('table1');出错, 我就不会写了,呵呵,晕菜!!
感谢楼上,一定结贴!!!
table_maxid表结构:
----名称-----数据类型---大小---小数位---是否为空?----默认值
tablename----varchar2----30---------------------------------
maxid----------number----10--------0------------------------
建表后,先插入一条记录:
insert into table_maxid (tablename,maxid) values ('table1',0);
存储过程:testproc
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
调用:
execute testproc('table1');出错, 我就不会写了,呵呵,晕菜!!
感谢楼上,一定结贴!!!
#4
CREATE PROCEDURE PROC_AUTOID @IDName char(10),@IDString char(20) out as
begin
Declare @length char(20),@tempid char(20),@tempkind Char(2),@templength int
Declare @tempint int
Declare @yy char(2),@mm char(2),@dd char(2),@tempdate char(6)
Declare ID_cursor Cursor For Select lastid,idname,idkind,idlength From autoid Where idname=@IDName
Open ID_cursor
Fetch Next From ID_cursor into @length,@tempid,@tempkind,@templength
set @length=rtrim(@length)
If @@FETCH_STATUS = 0
begin
if @tempkind='1'
begin
set @yy=convert(char(2),right(year(getdate()),2))
set @mm=convert(char(2),month(getdate()))
if (len(@mm)=1)
set @mm='0'+@mm
set @dd=convert(char(2),day(getdate()))
if (len(@dd)=1)
set @dd='0'+@mm
set @tempdate=@yy+@mm+@dd
if @tempdate=left(@length,6)
begin
set @tempint=convert(int, right(rtrim(@length),4))
set @tempint= @tempint+1
set @IDString=@tempdate+left('0000',4-len(@tempint))+convert(char,@tempint)
end
else
begin
set @IDString=@tempdate+'0001'
end
end
if @tempkind='2'
begin
if @length=null
begin
set @IDString='0001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('0000',4-len(@tempint))+convert(char,@tempint)
end
end
If @tempkind='3'
begin
If (@length=null) or (isnumeric(@length)=0)
begin
set @IDString='000001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('000000',6-len(@tempint))+convert(char,@tempint)
end
end
end
close ID_cursor
deallocate ID_cursor
update autoid set lastid=@IDString where idname= @IDName
select lastid from autoid where idname= @IDName
--客户编号加前缀‘N’
if @IDName='khbh'
set @IDString='N'+@IDString
end
GO
麻烦吧
还得建表autoid
调用
public String executeProc(String IDName)
{
String returnstr,sqlstr,rsstr;
rs=null;
sqlstr = "{call PROC_AUTOID(?,?)}";
try
{
if (conn!=null)
{
conn.close();
}
conn = DriverManager.getConnection(sConnStr,UseName,PassWord);
CallableStatement stmt = conn.prepareCall(sqlstr);
stmt.setString(1,IDName);
stmt.registerOutParameter(2,Types.CHAR);
rs=stmt.executeQuery();
rs.next();
rsstr = rs.getString(1);
returnstr = stmt.getString(2);
rs.close();
stmt.close();
conn.close();
}
catch (Exception erproc)
{
return null;
}
return returnstr;
}
begin
Declare @length char(20),@tempid char(20),@tempkind Char(2),@templength int
Declare @tempint int
Declare @yy char(2),@mm char(2),@dd char(2),@tempdate char(6)
Declare ID_cursor Cursor For Select lastid,idname,idkind,idlength From autoid Where idname=@IDName
Open ID_cursor
Fetch Next From ID_cursor into @length,@tempid,@tempkind,@templength
set @length=rtrim(@length)
If @@FETCH_STATUS = 0
begin
if @tempkind='1'
begin
set @yy=convert(char(2),right(year(getdate()),2))
set @mm=convert(char(2),month(getdate()))
if (len(@mm)=1)
set @mm='0'+@mm
set @dd=convert(char(2),day(getdate()))
if (len(@dd)=1)
set @dd='0'+@mm
set @tempdate=@yy+@mm+@dd
if @tempdate=left(@length,6)
begin
set @tempint=convert(int, right(rtrim(@length),4))
set @tempint= @tempint+1
set @IDString=@tempdate+left('0000',4-len(@tempint))+convert(char,@tempint)
end
else
begin
set @IDString=@tempdate+'0001'
end
end
if @tempkind='2'
begin
if @length=null
begin
set @IDString='0001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('0000',4-len(@tempint))+convert(char,@tempint)
end
end
If @tempkind='3'
begin
If (@length=null) or (isnumeric(@length)=0)
begin
set @IDString='000001'
end
else
begin
set @tempint=convert(int,@length)
set @tempint= @tempint+1
set @IDString=left('000000',6-len(@tempint))+convert(char,@tempint)
end
end
end
close ID_cursor
deallocate ID_cursor
update autoid set lastid=@IDString where idname= @IDName
select lastid from autoid where idname= @IDName
--客户编号加前缀‘N’
if @IDName='khbh'
set @IDString='N'+@IDString
end
GO
麻烦吧
还得建表autoid
调用
public String executeProc(String IDName)
{
String returnstr,sqlstr,rsstr;
rs=null;
sqlstr = "{call PROC_AUTOID(?,?)}";
try
{
if (conn!=null)
{
conn.close();
}
conn = DriverManager.getConnection(sConnStr,UseName,PassWord);
CallableStatement stmt = conn.prepareCall(sqlstr);
stmt.setString(1,IDName);
stmt.registerOutParameter(2,Types.CHAR);
rs=stmt.executeQuery();
rs.next();
rsstr = rs.getString(1);
returnstr = stmt.getString(2);
rs.close();
stmt.close();
conn.close();
}
catch (Exception erproc)
{
return null;
}
return returnstr;
}
#5
楼上,第一行返回下述错误:
行号= 1 列号= 29 错误文本= PLS-00103: 出现符号 "CREATE"在需要下列之一时: ( ; is with authid as cluster compress order using compiled wrapped external deterministic parallel_enable pipelined
这是什么意思啊?
行号= 1 列号= 29 错误文本= PLS-00103: 出现符号 "CREATE"在需要下列之一时: ( ; is with authid as cluster compress order using compiled wrapped external deterministic parallel_enable pipelined
这是什么意思啊?
#6
select ..for update;
#7
楼上的写法是sql server的t-sql语法,不适用于oracle。
不明白楼主为什么不用sequence,那简单很多啊
不明白楼主为什么不用sequence,那简单很多啊
#8
先执行+1操作
锁住记录:select col1 from tablename for update;
锁住记录:select col1 from tablename for update;
#9
to 弱水三千:不用序列是因为那一系列操作中一旦出错,就无法回滚,用存储过程就可以。如果你有好的方法,请告知,急啊
#10
不用序列,那只能你自己解决并发问题了,不是很容易的.
#11
如果我把存储过程写成这样:
存储过程名:testproc
内容:
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
比如里面有一条记录,
insert into table_maxid (tablename,maxid) values ('table1',0);
应怎么调用呢?
execute testproc('table1'...);
上面这行,有三个点的地方应怎么写呢?
请教!!
存储过程名:testproc
内容:
(table_name in varchar2, newmaxid out number)
as
begin
update Table_MaxID set MaxID = MaxID + 1 where TableName=table_name;
select maxid into newmaxid from Table_MaxID where TableName=table_name;
end;
比如里面有一条记录,
insert into table_maxid (tablename,maxid) values ('table1',0);
应怎么调用呢?
execute testproc('table1'...);
上面这行,有三个点的地方应怎么写呢?
请教!!
#12
up一下,再不解决就结贴了!