向大家问好,问一个非常难的问题。 谢谢(200分)

  • 主题发起人 isnotnull
  • 开始时间
I

isnotnull

Unregistered / Unconfirmed
GUEST, unregistred user!
有两个表,chdd, cxdd
结构如下:
chdd
chddh chdate
cd-2002-02-01-0001 2002-02-20
cd-2002-02-01-0002 2002-02-20
cd-2002-02-02-0001 2002-02-20
cd-2002-02-02-0002 2002-02-20


cxdd
cxddh cxdate
cx-2002-02-01-0001 2002-02-20
cx-2002-02-01-0002 2002-02-20
cx-2002-02-02-0001 2002-02-20
cx-2002-02-02-0002 2002-02-20

也就是 单据号每天取 最大单号+1(0001+1)作为新的编号,第二天又从
0001,0002开始增加,

可不可以用存储过程来实现,
又因为上面两个表结构都差不多, 只是最前的标识符不同,
一个是chdd-->cd-2000..一个是cxdd->cx-2000...

那可不可以把这存储过程写成一段公用的代码, 只要传递参数
(表名/chdd,cxdd,最前标识 ch,cx, 还有chdate, cxdate 把这些字符参数传递给存储过程)
就可以节省同样的代码, 对不。

谢谢!
 
不用吧,在添加记录的时候控制即可
只要在添加记录前判断一下最后一条记录是否是昨天的就行了,
如果最后一条是昨天则记录号从0001开始,如果是今天的则累加
 
create procedure GetNextID (@id char(2),@date char(10),@ReturnValue char(18))
as
begin
declare @sql varchar(1000)
declare @Maxid char(18)

begin tran

set @sql = 'declare cur_id cursor for select max('+@id+'ddh) from '+@id+'dd where '+@id+'date='''+@date+''''
exec(@sql)
Open cur_id
fetch next from cur_id into @Maxid
if @Maxid = null
set @ReturnValue=@id + '-'+@date+'-0001'
else
set @ReturnValue=@id + '-'+@date+replace(Str(cast(substring(@Maxid,15,4) as int)+1,4),' ','0')
Close cur_id
deallocate cur_id
set @sql = 'insert into ' + @id + 'dd (' + @id + 'ddh) values(''' + @ReturnValue+''')'
exec(@sql)
commit trans
end
未测试,Sqlserver2000语法
 
谢谢 Easylee,
也就是取出当天的最大记录+1作为 新的编号, 我有很多表都是这种结构的。
CF-2000-20-02-0001 .....只是标识不同,想用存储过程来完成一个公用的模块。
因为我现在还不熟悉存储过程,如果用dehpi写我肯定是可以写出来的, 写成一个函数,
传递表名,最前标符,还有取服务器的日期,再插入到表里。
我看了一下以前的贴子, 听他们说存储过程速度比delphi直接写的语句要快得多。

 
zm30 你好!
我把你上面的代码复制到查询分析器里执行,我怎样才得看到结构, 第一次运行没有错误,
执行完毕, 和二次告诉我已经存在了。

我想测试一下,但怎样测试, 也就是先不在程序里传参数。直接在查询分析器里传一个
已知的参数, 另外 ,如果还有外键约束, 怎样保证整性,用事务吗?
在dephi里我用过事务,在这里面怎样加。
 
改了一下上面的存储过程
在查询分析器里测试:
declare @a char(2)
declare @b char(10)
declare @OutId char(18)
set @a='ch'
set @b='2002-02-01'
exec GetNextID @a,@b,@OutID output
print @OutID
 
如果出错了怎么办,要加上rollback怎样加进去。 谢谢zm30,
 
就上面的代码执行

服务器: 消息 102,级别 15,状态 1,过程 GetNextID,行 21
在 'trans' 附近有语法错误。
 
这两句改一下
exec(@sql)
if @@error<>0
rollback tran
else
commit tran
 
大概意思: 找当天的最大号
select max(chddh) from chdd where chdate=today (为个你要重写)
如果返回空,新的一天开始的。应该知道怎么做。
不空,从chddh 取后四位+1
 
create procedure GetNextID (@id char(2),@tablename char(20),@date char(10),@ReturnValue char(18))
as
begin
declare @sql varchar(1000)
declare @Maxid char(18)

begin tran

set @sql = 'declare cur_id cursor for select max('+@id+'ddh) from @tablename where '+@id+'date='''+@date+''''
exec(@sql)
Open cur_id
fetch next from cur_id into @Maxid
if @Maxid = null
set @ReturnValue=@id + '-'+@date+'-0001'
else
set @ReturnValue=@id + '-'+@date+replace(Str(cast(substring(@Maxid,15,4) as int)+1,4),' ','0')
Close cur_id
deallocate cur_id
set @sql = 'insert into ' + @id + 'dd (' + @id + 'ddh) values(''' + @ReturnValue+''')'
exec(@sql)
if @@error<>0
rollback tran
else
commit tran
end

调用
declare @a char(2)
declare @b char(20)
declare @c char(10)
declare @OutId char(18)
set @a='cd'
set @b='cgdd'
set @b='2002-02-01'
exec GetNextID @a,@b,@c,@OutID output
print @OutID

出现错误
服务器: 消息 8162,级别 16,状态 2,过程 GetNextID,行 0
形式参数 '@ReturnValue' 定义为 OUTPUT,但实际参数却未声明为 OUTPUT。
 
什么问题,怎么看不见
 
表结构是这样的。
表名.
cgdd
cddh, cddate
char(18) datetime

create procedure GetNextID (@id char(2),@tablename char(20),@date char(10),@ReturnValue char(18))
as
begin
declare @sql varchar(1000)
declare @Maxid char(18)

begin tran

set @sql = 'declare cur_id cursor for select max('+@id+'dh) from @tablename where '+@id+'date='''+@date+''''
exec(@sql)
Open cur_id
fetch next from cur_id into @Maxid
if @Maxid = null
set @ReturnValue=@id + '-'+@date+'-0001'
else
set @ReturnValue=@id + '-'+@date+replace(Str(cast(substring(@Maxid,15,4) as int)+1,4),' ','0')
Close cur_id
deallocate cur_id
set @sql = 'insert into ' + @id + 'dd (' + @id + 'dh) values(''' + @ReturnValue+''')'
exec(@sql)
if @@error<>0
rollback tran
else
commit tran
end







declare @a char(2)
declare @b char(20)
declare @c char(10)
declare @OutId char(18)
set @a='cd'
set @b='cgdd'
set @c='2002-02-01'
exec GetNextID @a,@b,@c,@OutID output
print @OutID

出现错误
服务器: 消息 8162,级别 16,状态 2,过程 GetNextID,行 0
形式参数 '@ReturnValue' 定义为 OUTPUT,但实际参数却未声明为 OUTPUT


 
create procedure GetNextID (@id char(2),@tablename char(20),@date char(10),@ReturnValue char(18) output)
在后面加个output
 
因为我的表名是规则的,所以我上面就加了个传递 表名进去的参数。
set @sql = 'declare cur_id cursor for select max('+@id+'dh) from @tablename where '+@id+'date='''+@date+''''
//这里原来是ddh,我改为dh,

set @sql = 'insert into ' +@tablename+ '(' + @id + 'dh) values(''' + @ReturnValue+''')'
exec(@sql)

这两句我改了一下,又有了下面的问题

必须声明变量 '@tablename'。
服务器: 消息 16916,级别 16,状态 1,过程 GetNextID,行 11
名为 'cur_id' 的游标不存在。
服务器: 消息 16916,级别 16,状态 1,过程 GetNextID,行 12
名为 'cur_id' 的游标不存在。
服务器: 消息 16916,级别 16,状态 1,过程 GetNextID,行 17
名为 'cur_id' 的游标不存在。
服务器: 消息 16916,级别 16,状态 1,过程 GetNextID,行 18
名为 'cur_id' 的游标不存在。
 
@tablename要放在'号外面
生成Sql后要exec(@sql)
 
create table cgdd (
cddh char(20),
cddate char(20)
)

create procedure GetNextID (@id char(2),@tablename char(20),@date char(10),@ReturnValue char(18) output)
as
begin
declare @sql varchar(1000)
declare @Maxid char(18)

begin tran

set @sql = 'declare cur_id cursor for select max('+@id+'dh) from @tablename where '+@id+'date='''+@date+''''
exec(@sql)
Open cur_id
fetch next from cur_id into @Maxid
if @Maxid = null
set @ReturnValue=@id + '-'+@date+'-0001'
else
set @ReturnValue=@id + '-'+@date+replace(Str(cast(substring(@Maxid,15,4) as int)+1,4),' ','0')
Close cur_id
deallocate cur_id
set @sql = 'insert into ' + @tablename + '(' + @id + 'dh) values(''' + @ReturnValue+''')'
exec(@sql)
if @@error<>0
rollback tran
else
commit tran
end





declare @a char(2)
declare @b char(20)
declare @c char(10)
declare @Outid char(18)

set @a='cd'
set @b='cgdd'
set @c='2002-02-01'
exec GetNextID @a,@b,@c, @Outid output
print @OutID

这是我写的全部语句,你帮我看一下好吗?
 
create table cgdd (
cddh char(20),
cddate char(20)
)

Drop procedure GetNextID

create procedure GetNextID (@id char(2),@tablename char(20),@date
char(10),@ReturnValue char(18) output)
as
begin
declare @sql varchar(1000)
declare @Maxid char(18)

begin tran

set @sql = 'declare cur_id cursor for select max('+@id+'dh) from '+
@tablename+' where '+@id+'date='''+@date+''''
exec(@sql)
Open cur_id
fetch next from cur_id into @Maxid
if @Maxid is null
set @ReturnValue=@id + '-'+@date+'-0001'
else
set @ReturnValue=@id +
'-'+@date+'-'+replace(Str(cast(substring(@Maxid,15,4) as int)+1,4),' ','0')

Close cur_id
deallocate cur_id
set @sql = 'insert into ' + @tablename + '(' + @id + 'dh,'+@id+'date) values(''' +
@ReturnValue+''','''+@date+''')'
exec(@sql)
if @@error<>0
rollback tran
else
commit tran
end





declare @a char(2)
declare @b char(20)
declare @c char(10)
declare @Outid char(18)

set @a='cd'
set @b='cgdd'
set @c='2002-02-01'
exec GetNextID @a,@b,@c, @Outid output
print @OutID
 
谢谢zm30, 问题解决了。最后问一个问题,output的作用是输出一个结果对吗?

如果不加这个output, 那我在delphi里调用这个存储过程,是不会返回结果的对吗?
还是已经存储到变量
@ReturnValue 里面,再通过程序读@的内容 , output这个命令只在查询分器里为看到结果而添加的。对不
在程序里可以要这个参数吗?
 
顶部