这里所谓的流水号,仅仅是一个代称,是指数据库中字符串格式的自增长。例学生编码(系统自动生成P0001、P0002...,)
当然实现的方式也很多,如果不考虑并发和锁表问题的话,代码实现起来也容易。但是本次是通过最简单数据库函数来实现。
1:建表

CREATE TABLE [dbo].[studentinfo]( [StudentGuid] [nchar](10) NOT NULL, [Name] [nchar](10) NULL ) ON [PRIMARY]
2:创建函数

create function P_QIM_Print_Parm_mster() returns varchar(7) as begin declare @studentGuid varchar(7) select @studentGuid='P'+RIGHT(1000000+ISNULL(RIGHT(MAX(studentGuid),6),0)+1,6)--查找表中该列中的最大值取到后(右)6位,最大的+1 from StudentInfo return @studentGuid END
3:给表添加函数

ALTER TABLE studentinfo ADD DEFAULT ([dbo].[P_QIM_Print_Parm_mster]()) FOR StudentGuid
4:测试用例
但是这样会出现一个问题:每一个数据表都要维护一个函数。但是在函数中没有办法把表名和字段名当做参数传递,也没有办法执行exec。所以准备通过存储过程来实现
重要的是要把查询结果输出,而查询的表和内容都是通过sql拼接成的
一个小demo

CREATE TABLE [dbo].[Test]( [ID] [uniqueidentifier] NOT NULL, [Jan] [int] NULL, [Feb] [int] NULL, [Mar] [int] NULL, CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
创建一个存储过程

create procedure [dbo].[CalculateCode2] (@id nvarchar(120),@tableName nvarchar(50)) as begin declare @jan int,@feb int,@mar int, @str nvarchar(500); --@str 为拼接成的动态的sql, set @str= 'select @jan=jan,@feb=feb,@mar=mar from '+@tableName+' where id=@id' --sp_executesql 一用来执行动态的sql语句 --N''为动态拼接成的sql的内部参数列表,如果想把查询或计算的结果输出,那么就可以通过内部参数列表试一下 exec sp_executesql @str,N'@jan int out,@feb int out,@mar int out,@id nvarchar(120)',@jan out,@feb out,@mar out,@id; exec ('select * from '+@tableName) select @jan+@feb+@mar end exec [CalculateCode2] '6f9619ff-8b86-d011-b42d-00c04fc964ff','Test'
好,证明了技术的可行性后,那么需要根据我们的逻辑进行相应的存储过程的编写了

create procedure [dbo].[CalculateCode3] (@formatField nvarchar(30),@tableName nvarchar(50)) as begin declare @code nvarchar(20), @sql nvarchar(2000) ; --@str 为拼接成的动态的sql, set @sql= 'select @code = RIGHT(1000000+ISNULL(RIGHT(MAX('+@formatField+'),4),0)+1,4) from '+@tableName --sp_executesql 一用来执行动态的sql语句 --N''为动态拼接成的sql的内部参数列表,如果想把查询或计算的结果输出,那么就可以通过内部参数列表试一下 exec sp_executesql @sql,N'@code nvarchar(20) out', @code out; select @code end exec [CalculateCode3] 'StudentGuid','studentinfo'
代码实现版

Create procedure [dbo].[sp_CalculateCode] (@formatField nvarchar(30),@tableName nvarchar(50),@maxCode nvarchar(20) out ) as begin declare @code nvarchar(20), @sql nvarchar(2000) ; --@str 为拼接成的动态的sql, set @sql= 'select @code = RIGHT(1000000+ISNULL(RIGHT(MAX('+@formatField+'),4),0)+1,4) from '+@tableName --sp_executesql 一用来执行动态的sql语句 --N''为动态拼接成的sql的内部参数列表,如果想把查询或计算的结果输出,那么就可以通过内部参数列表试一下 exec sp_executesql @sql,N'@code nvarchar(20) out', @code out; set @maxCode = @code end

/// <summary> /// 通过存储过程从数据表中获取该表中编码最大值 /// </summary> /// <returns></returns> public string GetCode() { string equipmentCode = string.Empty; try { //ToDo: 这个地方还是直接写死吧,以后如果要到放置BaseBLL中的话可以提取这两个参数 string formatField = "EquipmentCode";//要自动排序的字段 string tableName = "AS_Equipment"; //要自动排序的表名 DbContext db = EFContextFactory.GetCurrentDbContext(); //02 设置参数 SqlParameter[] parameters = { new SqlParameter("@formatField",formatField), new SqlParameter("@tableName",tableName), new SqlParameter("@code", System.Data.SqlDbType.NVarChar,10) }; //指明输出参数 parameters[2].Direction = System.Data.ParameterDirection.Output; var slt = db.Database.SqlQuery<object>("exec [sp_CalculateCode] @formatField,@tableName,@code output", parameters); slt.ToList(); if (slt != null) { equipmentCode = parameters[2].Value.ToString(); } return equipmentCode; } catch (Exception) { throw; } }