sqlserver流水号,数据库流水号

SQL 流水号 按月怎么弄

您好,oracle数据库的话可以利用rownum取当前记录的顺序,然后赋值给流水号就可以了。

创新互联网络公司拥有10余年的成都网站开发建设经验,上千客户的共同信赖。提供网站制作、成都网站建设、网站开发、网站定制、外链、建网站、网站搭建、响应式网站、网页设计师打造企业风格,提供周到的售前咨询和贴心的售后服务

sqlserver可就没什么好办法了,只能alter table xxx add id nvarchar(10) indentity(1,1)了,然后再将id赋值流水号。

---定义当前的流水号,可以从数据库中获取,此处为测试值

DECLARE @CURR_LSH VARCHAR(7)

---新流水号

DECLARE @LSH VARCHAR(7)

---旧流水号第5位

DECLARE @FIRSTCHAR VARCHAR(1)

---旧流水号最后2位的数值

DECLARE @LASTCHAR2 INT

---旧流水号第5位的asc码

DECLARE @FIRSTCHARASCII INT

---新的后3位流水号

DECLARE @LASTCHAR3NEW VARCHAR(3)

---测试的旧流水号

SET @CURR_LSH = 'B307Z98'

---定义当前年份最后1位和两位的月份

DECLARE @YEAR VARCHAR(1)

DECLARE @MONTH VARCHAR(2)

SET @YEAR = SUBSTRING(CONVERT(VARCHAR,DATEPART(YEAR,GETDATE())),4,1)

SET @MONTH = RIGHT('0' + CONVERT(VARCHAR,DATEPART(MONTH,GETDATE())), 2)

SET @FIRSTCHAR = SUBSTRING(@CURR_LSH, 5,1)

SET @FIRSTCHARASCII = ASCII(@FIRSTCHAR)

---@FIRSTCHARASCII 48-57表示0-9,65-90表示A-Z

SET @LASTCHAR2 = CONVERT(INT,SUBSTRING(@CURR_LSH,6,2))

IF @LASTCHAR2 99

BEGIN

SET @LASTCHAR3NEW = @FIRSTCHAR + RIGHT('00' + CONVERT(VARCHAR, @LASTCHAR2 + 1),2)

END

ELSE

BEGIN

IF @FIRSTCHARASCII 57

SET @LASTCHAR3NEW = CONVERT(VARCHAR, CONVERT(INT,@FIRSTCHAR + '00') + CONVERT(INT, RIGHT('00' + CONVERT(VARCHAR, @LASTCHAR2 + 1),3)))

ELSE IF @FIRSTCHARASCII = 57

SET @LASTCHAR3NEW = 'A00'

ELSE

SET @LASTCHAR3NEW = CHAR(@FIRSTCHARASCII + 1) + '00'

END

---输出你需要的新流水号

SET @LSH = 'B' + @YEAR + @MONTH + @LASTCHAR3NEW

---打印出来

sqlserver:工作流的建表问题

我没太看明白你的需求,,,

大致给你个思路

流程单据表(这里不知道你这个表是干什么用的,按我的理解来给你说)

流程定义 流程编号

内容:请假 QJ

借款 JK

然后你的其他几个单据流水号,应该就是单据号

都以流程单据中的流程编号开头

例如请假单据流水号就为QJ20140422,,,,这样为结构

这样的话,你的凭证界面就能和你的流程单据有关联了;

当然也有其他的很多方式,也可以再给你提供一种

流程定义 流程编号 凭证号

内容:请假 QJ 001

借款 JK 002

加入凭证号,然后每种单据也加入凭证号字段,

例如请假单,就默认他的凭证号都为001,这样一样是可以有关联

你可以具体根据实际情况,考虑我给你的方式

如果用sqlserver该怎么实现按指定的格式实现流水号?

SQL Server 2012 版本, 新增了 序列号的功能。

可是实现类似的处理。

如果是 SQL Server 2008 或者以下版本的, 可以使用 identity + 计算列的处理机制。

oracle:

select 'P'||trim(to_char(patient_new_id.nextval,'009999999')) patient_id from dual

'P' 是 固定字符串.

|| 是 连接字符串

trim 是去除 字符串前后的空格

to_char 是把数字类型的, 转换为 字符类型

patient_new_id.nextval 这里的 patient_new_id 应该是一个序列号, nextval 是获取序列号的下一个值。

'009999999' 是 TO_CHAR 函数的 格式化字符串, 0 意味这如果数字不到这一位,那么也要显示0。

patient_id 是前面那个 'P' || ...... 查询结果的 别名。

from dual 是因为 Oracle 不允许你像 sql server 那样 select 1 这样的处理。 必须要 from 一个表, 因此只好 from 一个 只有1行数据的系统表。

怎么生成流水号

目前是在.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里实现的,实际使用中可以通过存储过程来实现。当然,这种方法对数据库的访问会比较频繁,另外,数据库表建立的时候必须插入一条初始值,这是代码不完善的地方,有时间的话我会去完善它。只是判断如果表内没有记录的情况下就插入一条初始记录,这个时候如何处理并发问题还没想明白。

SQL流水号?

oracle数据库的话可以利用rownum取当前记录的顺序,然后赋值给流水号就可以了。

sqlserver可就没什么好办法了,只能alter

table

xxx

add

id

nvarchar(10)

indentity(1,1)了,然后再将id赋值流水号吧

SQLSERVER 自动增长列根据时间更新

正好前几天干过这事儿。

首先需要定义一张流水号表:

--serialNumber是流水号表,每个type每个prefix只有一条记录,保存最新的流水号

create table serialNumber ([type] varchar(20),[prefix] varchar(20),SN int);

其次定义一个存储过程,根据指定的type和prefix,获得最新的流水号:

create procedure proc_getSN(@type varchar(20),@prefix varchar(20),@sn int output)

as

begin

set transaction isolation level serializable;

begin tran

--更新流水号

update serialNumber set SN=SN+1 where [type]=@type and [prefix]=@prefix;

if @@rowcount=0

begin

insert into serialNumber([type],[prefix],[SN]) values (@type,@prefix,1);

select @sn=1;--这里不要select from serialNumber了,否则会死锁

end

else

begin

select @sn=isnull(SN,0) from serialNumber where [type]=@type and [prefix]=@prefix;

end

commit;

set transaction isolation level read committed;

end

需要获取流水号的时候,像这样:

--[order]是订单表,生成订单号的规则是'C'+8位日期+4位流水号

declare @sn int;

exec proc_getSN 'contract','C20140105',@sn output;

insert into [order] 

select 'C20140105'+right('0000'+cast(@sn as varchar),4),'contract',...


本文题目:sqlserver流水号,数据库流水号
本文URL:http://azwzsj.com/article/phsggp.html