以文本方式查看主题 - Foxtable(狐表) (http://foxtable.net/bbs/index.asp) -- 专家坐堂 (http://foxtable.net/bbs/list.asp?boardid=2) ---- [分享][求助]采用存储过程完成复杂编号问题! (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=61788) |
-- 作者:jnletao -- 发布时间: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台电脑用于开单据,窗口全部采用快捷键辅助,开单速度很好,存在单据删除情况。并发获取编号的概率比较大。 以下为分析图,看不明白也不要紧,关键是在网速不佳,客户机电脑响应也慢的情况下,确实有重号的可能。 继续码字中,稍候…… |
-- 作者:jnletao -- 发布时间:2014/12/19 10:13:00 -- 拜读了飞飞老师 采用的存储过程[分享]各种编号问题的终极解决方案 的方案,于是想到将 程老师的方案 改为存储过程方式。 采用存储过程方式 的优点与方案: 原来数据的反复读取,插入,修改循环操作 改在服务端执行,而客户只访问服务器一次就可获取编号,减少访问次数,提高服务端运行效率! 存储过程还采用了三个自定义函数,专于替换原代码的count统计编号 min最小编号 max最大编号 下一楼放代码与源文件。 现在说下要求助老师们的问题。 1,存储过程【编号生成】在服务端测试正常,可是在狐表里 得不到值,求更正。 2,现在采用存储过程方式只是照搬程老师源码原理。依然不能解决重号问题。 问题关键应该是在存储过程执行中对编号表进行锁定与解锁。求解决。
|
-- 作者:有点甜 -- 发布时间:2014/12/19 10:17:00 -- 你怎么做的,然后又遇到什么问题?
写存储过程,跟直接写代码,没有什么区别啊 |
-- 作者:jnletao -- 发布时间:2014/12/19 10:17:00 -- 先上代码及表截图 |
-- 作者:jnletao -- 发布时间: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 以上为存储过程中用到的代码 下一楼 放源文件 |
-- 作者:有点甜 -- 发布时间:2014/12/19 10:32:00 -- 你这样做,跟直接写代码没有任何区别,而且还会增加别人入门的难度。 |
-- 作者:jnletao -- 发布时间:2014/12/19 10:33:00 -- 以下为源文件,数据库为mssql2005,附加 还原 都可以。 |
-- 作者:jnletao -- 发布时间:2014/12/19 10:41:00 -- 以下是引用有点甜在2014-12-19 10:32:00的发言: 你这样做,跟直接写代码没有任何区别,而且还会增加别人入门的难度。 解决了这两个问题可以说会带来极大的方便。再也不会出现编号重复问题了。而别人只需套用就行。 1,存储过程【编号生成】在服务端测试正常,可是在狐表里 得不到值,求更正。 2,现在采用存储过程方式只是照搬程老师源码原理。依然不能解决重号问题。 问题关键应该是在存储过程执行中对编号表进行锁定与解锁。求解决。
|
-- 作者:有点甜 -- 发布时间:2014/12/19 10:46:00 -- 存储过程,最后一句改成
select @Key1 |
-- 作者:有点甜 -- 发布时间:2014/12/19 10:49:00 -- 第二个问题
http://www.cnblogs.com/zfanlong1314/p/3698566.html
|