步步为营-106-“流水号”自增长

这里所谓的流水号,仅仅是一个代称,是指数据库中字符串格式的自增长。例学生编码(系统自动生成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;
            }

        }
C#代码实现
原文地址:https://www.cnblogs.com/YK2012/p/9472276.html