Foxtable(狐表)用户栏目专家坐堂 → [分享][求助]采用存储过程完成复杂编号问题!


  共有5058人关注过本帖树形打印复制链接

主题:[分享][求助]采用存储过程完成复杂编号问题!

帅哥哟,离线,有人找我吗?
jnletao
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
[分享][求助]采用存储过程完成复杂编号问题!  发帖心情 Post By:2014/12/19 9:50:00 [只看该作者]

最初拜读了程兴刚老师的编号解决方案,且已在项目应用中。
程兴刚老师的编号解决方案的优点:
1.能补号。
2.在单据新建时能即时显示编号,而不是临时编号。
3.可按类别,日期等创建复杂连续编号而互不影响。
程兴刚老师原贴:http://foxtable.com/bbs/dispbbs.asp?BoardID=2&ID=26913&replyID=&skin=1  [分享] 新版《网络环境下复杂的不重复编号》 

但在客户最近的反馈中,偶尔会出现编号重复的问题。
经常这几天的分析与查找,发现在一些极端情况下会发生重复。
pc005637老师的类似分析  [讨论]程版新版《网络环境下复杂的不重复编号》的读后疑问. 
说下环境极端情况:客户采用局域网办公,但不知什么原因,内部联MSSQL数据服务器的速度也不快。
20台电脑用于开单据,窗口全部采用快捷键辅助,开单速度很好,存在单据删除情况。并发获取编号的概率比较大。
以下为分析图,看不明白也不要紧,关键是在网速不佳,客户机电脑响应也慢的情况下,确实有重号的可能。

图片点击可在新窗口打开查看此主题相关图片如下:11qq截图201322.png
图片点击可在新窗口打开查看

继续码字中,稍候……



 回到顶部
帅哥哟,离线,有人找我吗?
jnletao
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
  发帖心情 Post By:2014/12/19 10:13:00 [只看该作者]

拜读了飞飞老师 采用的存储过程[分享]各种编号问题的终极解决方案 的方案,于是想到将 程老师的方案  改为存储过程方式。
采用存储过程方式 的优点与方案:
原来数据的反复读取,插入,修改循环操作 改在服务端执行,而客户只访问服务器一次就可获取编号,减少访问次数,提高服务端运行效率!
存储过程还采用了三个自定义函数,专于替换原代码的count统计编号  min最小编号  max最大编号
下一楼放代码与源文件。

现在说下要求助老师们的问题。
1,存储过程【编号生成】在服务端测试正常,可是在狐表里 得不到值,求更正。
2,现在采用存储过程方式只是照搬程老师源码原理。依然不能解决重号问题。
问题关键应该是在存储过程执行中对编号表进行锁定与解锁。求解决。

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/12/19 10:17:00 [只看该作者]

 你怎么做的,然后又遇到什么问题?

 

 写存储过程,跟直接写代码,没有什么区别啊


 回到顶部
帅哥哟,离线,有人找我吗?
jnletao
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
  发帖心情 Post By:2014/12/19 10:17:00 [只看该作者]

先上代码及表截图

图片点击可在新窗口打开查看此主题相关图片如下:qq1截图20141014101753.png
图片点击可在新窗口打开查看


图片点击可在新窗口打开查看此主题相关图片如下:qq2截图2014101410183812.png
图片点击可在新窗口打开查看


图片点击可在新窗口打开查看此主题相关图片如下:qq3截图20141014101946333.png
图片点击可在新窗口打开查看



 回到顶部
帅哥哟,离线,有人找我吗?
jnletao
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
  发帖心情 Post By:2014/12/19 10:24:00 [只看该作者]

用到的表代码:
USE [编号测试]
GO
/****** 对象: Table [dbo].[编号] 脚本日期: 10/14/2014 10:21:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[编号](
[_Identify] [int] IDENTITY(1,1) NOT NULL,
[_Locked] [bit] NULL,
[_SortKey] [numeric](28, 14) NULL,
[前缀] [nvarchar](25) NULL,
[顺序号] [int] NULL,
[表名] [nvarchar](50) NULL,
[已用标识] [bit] NULL,
[日期] [datetime] NULL,
CONSTRAINT [PrimaryKey_编号] PRIMARY KEY NONCLUSTERED
(
[_Identify] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

USE [编号测试]
GO
/****** 对象: Table [dbo].[费用记录单] 脚本日期: 10/14/2014 10:22:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[费用记录单](
[_Locked] [bit] NULL,
[_SortKey] [decimal](18, 0) NULL,
[制单人] [nvarchar](16) NULL,
[制单时间] [datetime] NULL,
[费用单号] [nvarchar](255) NULL,
[_Identify] [int] IDENTITY(1,1) NOT NULL,
[收费单位] [nvarchar](50) NULL,
CONSTRAINT [PK_收费记录单] PRIMARY KEY CLUSTERED
(
[_Identify] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

存储过程代码:
USE [编号测试]
GO
/****** 对象: StoredProcedure [dbo].[编号生成] 脚本日期: 10/14/2014 10:23:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[编号生成]
@cprefix nvarchar(255) = "AAAA141013-", --前缀
@ctablename nvarchar(255) = "费用记录单" --表名
--@BH int OUTPUT --新编号
AS

BEGIN
SET NOCOUNT ON
DECLARE @Key1 int,@Key2 int,@countid int
set @countid = dbo.countBH(@cprefix,@ctablename)
if @countid = 0
BEGIN
Insert Into [编号] (表名, 日期, 前缀, 顺序号, 已用标识) Values(@ctablename,getdate(),@cprefix,1,0)
END
set @Key1 = dbo.minBH(@cprefix,@ctablename)
set @Key2 = dbo.maxBH(@cprefix,@ctablename)
Update [编号] Set [已用标识] = 1 Where [顺序号] = @Key1 And [前缀] = @cprefix And 表名 = @ctablename
if @Key1 = @Key2
BEGIN
Insert Into [编号] (表名, 日期, 前缀, 顺序号, 已用标识) Values(@ctablename,getdate(),@cprefix,@Key2 + 1,0)
END
DELETE FROM [编号] Where 表名 = @ctablename and 前缀 = @cprefix and 顺序号 = @Key1 And 已用标识 = 1
return @Key1
END

三个自定义函数代码:
USE [编号测试]
GO
/****** 对象: UserDefinedFunction [dbo].[countBH] 脚本日期: 10/14/2014 10:24:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--编号表是否存在前缀的行
create function [dbo].[countBH](@prefixbh varchar(255),@tablename varchar(255))
returns int
as
begin
declare @mycount int
select @mycount=Count(*) from [编号]
Where [前缀] = @prefixbh And 表名 = @tablename and 已用标识 = 0
return @mycount
end


USE [编号测试]
GO
/****** 对象: UserDefinedFunction [dbo].[maxBH] 脚本日期: 10/14/2014 10:24:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--编号表是否存在前缀的行
create function [dbo].[maxBH](@prefixbh varchar(255),@tablename varchar(255))
returns int
as
begin
declare @mymaxbh int
Select @mymaxbh=Max(顺序号) From [编号]
Where [前缀] = @prefixbh And 表名 = @tablename and 已用标识 = 0
return @mymaxbh
end


USE [编号测试]
GO
/****** 对象: UserDefinedFunction [dbo].[minBH] 脚本日期: 10/14/2014 10:25:00 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--编号表是否存在前缀的行
CREATE function [dbo].[minBH](@prefixbh varchar(255),@tablename varchar(255))
returns int
as
begin
declare @myminbh int
Select @myminbh=Min(顺序号) From [编号]
Where [前缀] = @prefixbh And 表名 = @tablename and 已用标识 = 0 Or 已用标识 Is Null
return @myminbh
end


以上为存储过程中用到的代码

下一楼 放源文件





 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/12/19 10:32:00 [只看该作者]

 你这样做,跟直接写代码没有任何区别,而且还会增加别人入门的难度。

 回到顶部
帅哥哟,离线,有人找我吗?
jnletao
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
  发帖心情 Post By:2014/12/19 10:33:00 [只看该作者]

以下为源文件,数据库为mssql2005,附加 还原 都可以。

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:不重复编号测试.zip




图片点击可在新窗口打开查看此主题相关图片如下:qq4截图2014101410334744.png
图片点击可在新窗口打开查看

图片点击可在新窗口打开查看此主题相关图片如下:qq55截图20141014103505557.png
图片点击可在新窗口打开查看


 回到顶部
帅哥哟,离线,有人找我吗?
jnletao
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:941 积分:7786 威望:0 精华:0 注册:2013/7/7 13:37:00
  发帖心情 Post By:2014/12/19 10:41:00 [只看该作者]

以下是引用有点甜在2014-12-19 10:32:00的发言:
 你这样做,跟直接写代码没有任何区别,而且还会增加别人入门的难度。


解决了这两个问题可以说会带来极大的方便。再也不会出现编号重复问题了。而别人只需套用就行。


1,存储过程【编号生成】在服务端测试正常,可是在狐表里 得不到值,求更正。
2,现在采用存储过程方式只是照搬程老师源码原理。依然不能解决重号问题。
问题关键应该是在存储过程执行中对编号表进行锁定与解锁。求解决。

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/12/19 10:46:00 [只看该作者]

 存储过程,最后一句改成

 

select @Key1


 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/12/19 10:49:00 [只看该作者]


 回到顶部
总数 21 1 2 3 下一页