帮你写个
/// <summary>
        /// 根据时间生成流水号
        /// 流水号组成如XS200811050001
        /// XS:销售
        /// 20081105:日期
        /// 0001:20081105日的第一个订单
        /// </summary>
        /// <returns></returns>
        private string GetNumberString()
        {
            string orderNumber = null;
            //取得当天的最大订单号
            DateTime now = DateTime.Now;
            string sql = "select max(convert(int,substring(OrderNumber,11,4))) from Orders where OrderNumber like 'XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + "%'";
            DataSet ds = null;
            using (DatabaseOperater2 op = new DatabaseOperater2())
            {
                ds = op.ExcuteSelectByAdater(sql);
            }
            if (ds.Tables[0].Rows[0][0] is DBNull)
            {
                //如果今天还没有订单
                orderNumber = "XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + "0001";
            }
            else
            {
                //如果有订单,则在最大订单号上+1
                int number = Convert.ToInt32(ds.Tables[0].Rows[0][0])+1;
                orderNumber = "XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + number.ToString("d4");
            }
            return orderNumber;
        }
‘贰’ SQL怎样自动生成编号格式如:GG+YYYYMMDD+4位流水编号
我的项目里也用到这种模式
但有点不好,灵活性太差,逻辑判断都放在程序里,我刚写的改进下。
CREATE PROC CreateMaxNum
(
  @NumberHeader NVARCHAR(40)  --号码单头类型
)
DECLARE @NumberHeader  NVARCHAR(40), --编号头
        @NumberMiddle  CHAR(8),   --编号中间规则
        @MaxNum  CHAR(8),    --编号最大流水号
        @SQL NVARCHAR(4000)
SET @NumberMiddle= CONVERT(CHAR(8),GETDATE(),112) --设置中间编码规则
SET @SQL = 'SELECT @Num=RIGHT(''0000''+LTRIM(MAX(RIGHT(号码,4))+1),4) 
            FROM 号码表
            WHERE 号码 LIKE '''+ @NumberHeader+'%'' ';
EXEC sp_executesql @Sql,N'@Num NVARCHAR(40) OUTPUT',@MaxNum OUT
IF  @MaxNum IS NULL  --不存在该类型的号码,插入流水号为1的号码,
  BEGIN
     SELECT @NumberHeader + @NumberMiddle + '0001' 
  END
ELSE 
  BEGIN              --生成最大流水号
     SELECT @NumberHeader + @NumberMiddle + @MaxNum
  END
‘叁’ 求教sql server创建序列,生成流水号,急用 谢谢了
SEQ_HA_PERSON_INFO这个是什么?
既然是流水号,为什么又说由序列SEQ_HA_PERSON_INFO生成?
流水号不是一个个的增加上去的吗?
真心不明白
 
不过实现的方法2种
1、触发器在插入的时候生成
2、函数,插入前生成,或者插入时生成(直接在vaLues中写上就好)
‘肆’ 怎么生成流水号
目前是在.net中使用的这个方法,使用sqlserver的时间戳来控制并发情况下容易产生重复序列号的问题。
原理类似hibernate的主键生成机制,在系统启动时从数据库中读出最大的流水号,赋给一个类的静态变量,需要时,从该静态变量中取得流水号,加1后,就是你要的值。
代码:
public class testA {
public static Long maxNo;
static {
synchronized(maxNo){
maxNo = select max(maxNo) from DB;
}
}
public synchronized static long getMaxNo(){
return(++maxNo);
}
}
优点:保证同步,不会取到相同的值,同时避免了数据库的反复读取。
缺点:在cluster环境下
还是用上面的方法,但是只能在一台机器上发布并且绑定到JNDI,别的机器可以通过配置文件得知去哪里产生maxNo(实际上,每台机器都可以发布,但是所有机器只能去访问指定的一台机器),这样的效率虽然低了点,但是还是觉得比每次去数据库里取好点。当然,可以改进,就是再加一个本地类,每次去JNDI那里的类去取数据时,一次取20个回来(就是JNDI上面的类一次要加20),以后本地就用这20个值,用完了,再去JNDI上面的类去取。
当然,前面的这两个例子都比较复杂,甚至还有人提出用单态的方法。而我在.net中用的就比较简单了。方法如下:
在数据库(sqlserver)中新建一张表(sequence_num),专门用来生成流水号。
字段1:s_id,varchar(50),notnull
字段2:tmstmp,timestamp,notnull
代码如下:
public string getOderid()
  {
private SqlConnection conn = null;
   private SqlCommand comm = null;
  
   private string s_id = "";
   private byte [] tmstmp;//时间戳类型在.net中对应为一个byte数组
   private int s_idplus = 0;
   private string orderid = "";
   try
   {
    conn = SqlConn.getConn();
    conn.Open();
    do
    {
     string sqlQuery = "select s_id,tmstmp as tmstmp from sequence_num";
     comm = conn.CreateCommand();
     comm.CommandText = sqlQuery;
     SqlDataAdapter da = new SqlDataAdapter(comm);
     DataTable dt = new DataTable();
     dt.Clear();
     da.Fill(dt);
comm.Parameters.Clear();
if (!dt.Rows[0]["s_id"].ToString().Substring(0,12).Equals(DateTime.Now.ToString("yyyyMMddHHmm")))//每一分钟重置一次计数,实际上我认为每天重置一次比较好
     {
      s_id = DateTime.Now.ToString("yyyyMMddHHmm")+"0001";
      tmstmp = (byte[])dt.Rows[0]["tmstmp"];
     }
     else
     {
      s_id = dt.Rows[0]["s_id"].ToString();
      tmstmp = (byte[])dt.Rows[0]["tmstmp"];
s_idplus = Convert.ToInt32(s_id.Substring(12)) + 1;
      s_id = s_id.Substring(0,12)+Convert.ToString(s_idplus).PadLeft(4,'0');
     }
string sqlUpdate = "update sequence_num set s_id = @s_id where tmstmp = @tmstmp";//保证在记录未被修改的情况下更新,如果更新不成功,则重走一遍生成序列号的流程
     comm.CommandText = sqlUpdate;
comm.Parameters.Clear();
comm.Parameters.Add("@s_id",SqlDbType.VarChar,50);
     comm.Parameters["@s_id"].Value = s_id;
     comm.Parameters.Add("@tmstmp",SqlDbType.Timestamp);
     comm.Parameters["@tmstmp"].Value = tmstmp;
    }
    while(comm.ExecuteNonQuery()<=0);
   }
   catch(SqlException ex)
   {
    string aaa = ex.Message;
   }
   finally
   {
    if(conn!=null)
    {
     conn.Close();
    }
   }
   return s_id;
  }
这个流程都是在.net里实现的,实际使用中可以通过存储过程来实现。当然,这种方法对数据库的访问会比较频繁,另外,数据库表建立的时候必须插入一条初始值,这是代码不完善的地方,有时间的话我会去完善它。只是判断如果表内没有记录的情况下就插入一条初始记录,这个时候如何处理并发问题还没想明白。
