帮我看一下我写的两个存储过程,在多台机器同时执行的时候,有可能只执行一句,谢谢帮忙,在线等

liuyangxwg 2006-04-16 04:57:17
下面的两个存储过程是用来给给顾客发会员卡和会员卡冲消费积分金额的,第一个存储过程有时候无法
把变参中的的数据插入tr_customer表中,第二个存储过程,如果是本店卡和当日的信用卡,将从retjels中取xulh,riqi,shoukyh三个字段插入tr_jifen表,然后把retjels中当前xulh的yishj更新为否。但是,如果再多台机器同时写入的时候,此存储过程可能会只运行
create PROCEDURE tr_jifen_pro
(
@cd char(8) ,
@xph char(12) ,
@kh decimal(15,2),
@ky char(6)
--设置变参
)
AS
if not exists --判断下面的select是否返回值,如果不返回值,执行下面的语句,如果返回跳到else
(select 1 from tr_customer where cardno =@cd) --直接判断卡号是否在tr_customer表中
begin
insert into tr_jifen
(cardno,xulh,riqi,shishje,kouhj,jiqrq,shoukyh,jfsky,ontime)
select '非本店卡',xulh,riqi,shishje,@kh,convert(char(10),getdate(),120),shoukyh,@ky,convert(char(10),getdate(),8)
from retjels
where xulh=@xph and yishj='否' --当选定的小票号在retjels中的yishj字段为否,查询纪录插入tr_jifen表

end
else
begin

insert into tr_jifen
(cardno,xulh,riqi,shishje,kouhj,jiqrq,shoukyh,jfsky,ontime)
select @cd,xulh,riqi,shishje,@kh,convert(char(10),getdate(),120),shoukyh,@ky,convert(char(10),getdate(),8)
from retjels
where xulh=@xph and yishj='否' ----当选定的小票号在retjels中的yishj字段为否,查询纪录插入tr_jifen表
update retjels set yishj='是' where xulh=@xph --当选定的小票号在retjels中的yishj字段为是

update tr_jifen set xulh='非本日小票' where jiqrq<>riqi and cardno=@cd


end

select top 10 *
from tr_jifen
where jfsky=@ky
order by ontime desc

GO

上面的存储过程,所用到的表及其结构
retjels中的字段有,xulh,riqi,shoukyh,yishj
tr_customer的表结构
create table tr_customer --创建新tr_customer表
(
xh int identity(1,1),
cardno char(8) not null,
certif_no char(18) not null,
certif char(8) not null,
uname char(8) not null,
sex char(2) null,
phone char(12) null,
fkrq char(10) null
)
tr_jifen表的结构
create table tr_jifen --创建新tr_jifen表
(
cardno char(8) not null,
xulh char(12) not null,
riqi char(10) null,
shishje decimal(15,2) null default 0,
kouhj decimal (15,2) null default 0,
jiqrq char(10) null,
shoukyh char(6) null,
jfsky char(6) null,
ontime char(10) null,
beizhu char(50) null
)
...全文
191 13 点赞 打赏 收藏 举报
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
vovo2000 2006-04-19
恩 可能是并发问题了。
试一试提高事物隔离级别
set transaction isolation level


--------
语法
SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}

参数
READ COMMITTED

指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。

READ UNCOMMITTED

执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。

REPEATABLE READ

锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。

SERIALIZABLE

在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

注释
一次只能设置这些选项中的一个,而且设置的选项将一直对那个连接保持有效,直到显式更改该选项为止。这是默认行为,除非在语句的 FROM 子句中在表级上指定优化选项。

SET TRANSACTION ISOLATION LEVEL 的设置是在执行或运行时设置,而不是在分析时设置。

示例
下例为会话设置 TRANSACTION ISOLATION LEVEL。对于每个后续 Transact-SQL 语句,SQL Server 将所有共享锁一直控制到事务结束为止。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
SELECT * FROM publishers
SELECT * FROM authors
...
COMMIT TRANSACTION

  • 打赏
  • 举报
回复
撸大湿 2006-04-19
这个是我帮你写的?



但是还没有解决同时插入时无法插入的问题??

什么意思?并发问题?
  • 打赏
  • 举报
回复
liuyangxwg 2006-04-18
create PROCEDURE tr_jifen_pro
(
@cd char(8) ,
@xph char(12) ,
@kh decimal(15,2),
@ky char(6)
--设置变参
)
AS


if not exists --判断下面的select是否返回值,如果不返回值,执行下面的语句,如果返回跳到else
(select 1 from tr_customer where cardno =@cd) --直接判断卡号是否在tr_customer表中
begin
insert into tr_jifen
(cardno,xulh,riqi,shishje,kouhj,jiqrq,shoukyh,jfsky,ontime)
select '非本店卡',xulh,riqi,shishje,@kh,convert(char(10),getdate(),120),shoukyh,@ky,convert(char(10),getdate(),8)
from retjels
where xulh=@xph
and xulh not in (select distinct xulh from tr_jifen where riqi=convert(char(10),getdate(),120) and cardno<>'非本店卡') --当选定的小票号在retjels中的yishj字段为否,查询纪录插入tr_jifen表

end
else
begin
insert into tr_jifen
(cardno,xulh,riqi,shishje,kouhj,jiqrq,shoukyh,jfsky,ontime)
select @cd,xulh,riqi,shishje,@kh,convert(char(10),getdate(),120),shoukyh,@ky,convert(char(10),getdate(),8)
from retjels
where xulh=@xph
and xulh not in (select distinct xulh from tr_jifen where riqi=convert(char(10),getdate(),120) and cardno<>'非本店卡')
----当选定的小票号在retjels中的yishj字段为否,查询纪录插入tr_jifen表
end

select top 10 *
from tr_jifen
where jfsky=@ky
and riqi=convert(char(10),getdate(),120)
order by ontime desc
GO
存储过程我修改了一下,虽然解决了最后不进行update的问题,但是还没有解决同时插入时无法插入的问题。






  • 打赏
  • 举报
回复
koskinen 2006-04-18
关注一下,顺便接分
  • 打赏
  • 举报
回复
liuyangxwg 2006-04-17
单机执行没有任何问题,但是多台机器同时执行,就会有无法插入的现象,但是最后一个update是执行的
  • 打赏
  • 举报
回复
liuyangxwg 2006-04-17
当然眼熟了,你帮我写的,后来我自己修改了一些
  • 打赏
  • 举报
回复
撸大湿 2006-04-17
在查询分析器里调试一下
看看结果


表中是否有触发器?是否有死锁?比如事务处理之类的
  • 打赏
  • 举报
回复
dp_555 2006-04-17
友情接分。。。
  • 打赏
  • 举报
回复
撸大湿 2006-04-17

有点眼熟,好象再哪见过
  • 打赏
  • 举报
回复
云中客 2006-04-17
SQL在连续执行一些语句时可能会出现不能执行的情况,原因不太清楚,一般情况下我是将执行快的放在前面执行,相反的放在后面执行
  • 打赏
  • 举报
回复
liuyangxwg 2006-04-16
谢谢您的帮助,刚接触SQL,本人较穷,现在就是看联机帮助和CSDN
  • 打赏
  • 举报
回复
netcup 2006-04-16
我觉得好象很多SQL的资料书里都有类似的案例的.象我买的SQL 2000 BIBLE中就有,比如第一个存储过程改为:
if not exists
(select 1 from tr_customer where cardno=@cd or CERTIF_NO=@cto)
--判断变参中的卡号和身份证号是否在tr_customer表中存在,存在返回1值
insert into tr_customer
(cardno,certif_no,certif,uname,sex,phone,fkrq)
select @cd,@cto,@ctf,@xm,@xb,@tel,convert(char(10),getdate(),120)--返回当前日期
select @inerror=@@error
if @inerror<>0
begin
print '插入失败'
return @inerror
end
select xh as 序号,cardno,certif_no,certif,uname,sex,phone,fkrq
from tr_customer
where cardno=@cd

只要流程语句写好了就可以达到你的要求了.
  • 打赏
  • 举报
回复
liuyangxwg 2006-04-16
上面的是第二个存储过程,第一个存储过程拉下了
在这里
CREATE PROCEDURE tr_customer_pro
(
@cd char(8) ,
@cto char(18) ,
@ctf char(8) ,
@xm char(8) ,
@xb char(2) ,
@tel char(12)
)

as
if not exists
(select 1 from tr_customer where cardno=@cd or CERTIF_NO=@cto)
--判断变参中的卡号和身份证号是否在tr_customer表中存在,存在返回1值
insert into tr_customer
(cardno,certif_no,certif,uname,sex,phone,fkrq)
select @cd,@cto,@ctf,@xm,@xb,@tel,convert(char(10),getdate(),120)--返回当前日期

select xh as 序号,cardno,certif_no,certif,uname,sex,phone,fkrq
from tr_customer
where cardno=@cd
  • 打赏
  • 举报
回复
相关推荐
发帖
MS-SQL Server
加入

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2006-04-16 04:57
社区公告
暂无公告