主键生成器

这些天忙着做毕业设计,忙着敲代码,早发现像原来那样“无聊”的把那些技术文字再敲一遍是没有多大意义的,因为写出它们所用的时间要是仔细在看或者再用代码做几个实际的例子应该更好吧,其实这是早知道的,那以前知道还那么干,主要是因为太想做老师了吧!现在呢,不那么干不写了是因为暂时放弃做老师的打算吧,这两天空闲的时候复习数据库,翻到了以前的所写的一个存储过程“主键生成器”,SQLServer版本的是在以前项目中用过的,Oracle版本的是后面学习Oracle时补上的,不管怎么样,有看了一遍,敲了一遍,将来面视的时候也许用得着吧。

SQLServer版

USE TEST

IF EXISTS (SELECT name FROM sysobjects    --检查系统中是否 有与自定义存储过程同名的对象

         WHERE name = 'getNo' AND type = 'P')

   DROP PROCEDURE getNo

GO

  CREATE PROCEDURE getNo 

                  @precRecord varchar(10),    --3个参数。第1个 为输入参数(表名);第3个 为输入

          --参数(用以判断输出格式);; 第2个 为输出参数 (最后生成的主键编号)

                  @primarykey varchar(12) output ,           --若第3个参数等于0时,主键= 字轨+时期+编号 

                          -- 若第3个参数等于1时,主键=字轨+编号

                  @sign  smallint                                  --         若第3个参数等于其他时 报错

AS

    declare @prctmpdate datetime,                        --临时变量,用以记录存储过程中的中间变量

        @today datetime,

        @tmpprenum   varchar(4),

        @tmpword   varchar(2),

        @year1  varchar(2),

        @day1   varchar(2),

        @month1 varchar(2) ------------------------------------------------------------------------------------------------------------

set @today = getdate()

if not exists(select fRecord from tbrecno where fRecord=@precRecord)   --若表中没有与参数1同名的则新插入一条

   begin

  insert into tbrecno  (fRecord,Predate,Prenum,Word) values(@precRecord,@today,1,left(@precRecord,2))

   end

else

   begin

       select @prctmpdate=Predate from tbrecno where fRecord=@precRecord

       if ( datediff (day, @today , @prctmpdate ) < 0 )   --比较    若当前日期<上次日期  ,令  

                   --上次日期=上次日期 且 上次编号置为零

           begin

             update tbrecno  set Prenum = '1' ,predate = @today where fRecord=@precRecord

           end 

       else if (datediff(day,  @today , @prctmpdate ) = 0 )  --若当前日期=上次日期  ,令上次编号加一

           begin

             update tbrecno set Prenum = Prenum + 1 where fRecord=@precRecord     

           end

       else if ( datediff (day, @today , @prctmpdate ) > 0 )               --若当前日期〈上次日期  ,报错

           begin

             raiserror ('the db server date erreor  check system date please!', 16, 1)

           end

  end

---------------------------------------------------------------------------------------------------------------

 

  select  @prctmpdate=Predate,@tmpword=Word, @tmpprenum=prenum from tbrecno where fRecord=@precRecord

  select @tmpprenum=                                                                --上次编号不够四位的补够四位

              case len(ltrim(rtrim(@tmpprenum)))

               when 1 then '000'+rtrim(ltrim(@tmpprenum))

                when 2 then '00'+ rtrim(ltrim(@tmpprenum))

                when 3 then '0'+  rtrim(ltrim(@tmpprenum))

                when 4 then       rtrim(ltrim(@tmpprenum))

              end

-----------------------------------------------------------------------------------------------------------------

set @year1 =right(ltrim(rtrim((str(year(@prctmpdate ))))),2)                      --取出年份

select @month1=

               case len (ltrim(str(month(@prctmpdate))))                   --取出月份,若不够两位的补够两位

                 when 1 then '0'+ltrim(str(month(@prctmpdate )))

                 when 2 then     ltrim(str(month(@prctmpdate )))

               end

select @day1=                                                                        --取出天数,若不够两位的补够两位

               case len (ltrim(str(day(@prctmpdate))))

                 when 1 then '0'+ltrim(str(day(@prctmpdate )))

                 when 2 then  ltrim(str(day(@prctmpdate )))

               end

----------------------------------------------------------------------------------------------------------------

 if @sign=1

    begin                                                                             --判断输出类型

       set  @primarykey =rtrim(ltrim(@tmpword))+ @tmpprenum

    end

 else if   @sign=0

    begin

        set @primarykey = @tmpword+ @year1 + @month1 + @day1 + @tmpprenum

    end

 else

    begin

      raiserror ('parameter error', 16, 1)  

    end

--------------------------------------------------------------------------

GO

-------------------------------------------------------------------

--                                    测试

declare @mybillno varchar(12) 

 exec getNo 'pG', @mybillno output,0

  select @mybillno

--  IF EXISTS (select * from Tbrecno where word = left(ltrim(rtrim( @precRecord )),2))

      --    raiserror ('表名的前两个字母与已有的发生冲突 请修改表名', 16, 1)

-- delete tbrecno

--
--select * from tbrecno
Oracle版

create or replace procedure getmykeyno(
sign varchar2,
tablename varchar2,
outkey out varchar2
)
is

-- sign getmykey.my_ziguei %type; 
-- tablename getmykey.my_tablename %type; 
--outkey varchar(20);

lastdate getmykey.my_lastdate%type;
tmpint getmykey.my_lastno %type;
nowdate date;
tmpStr varchar(4);
tmpsign varchar(2);

myyear int;
mymonth int;
myday int;

tmpcount int;

begin
myyear := extract(year from sysdate);
mymonth := extract(month from sysdate);
myday := extract(day from sysdate);

nowdate:=sysdate;
--tablename:='aaaa';
--sign:='ad';

select count(*) into tmpcount from getmykey where my_tablename = tablename;
if tmpcount=0 then

   begin
      insert into getmyke(my_tablename,my_ziguei,my_lastno,my_lastdate) values          (tablename,sign,1,nowdate) ;tmpInt := 1;
end;
else 
select my_lastdate into lastdate from getmykey where my_tablename=tablename ;

if (myyear>=extract(year from lastdate) and mymonth>=extract(month from lastdate)) then

if(myday=extract(day from lastdate)) then

update getmykey set my_lastno = my_lastno + 1 where my_tablename=tablename; 
select my_lastno into tmpint from getmykey where my_tablename=tablename;

else 
if (myday > extract(day from lastdate)) then

update getmykey set my_lastno = 1 where my_tablename=tablename ;
update getmykey set my_lastdate = nowdate where my_tablename=tablename;
tmpInt := 1 ;
else 
dbms_output.put_line('服务器的时间改变,请检查系统!');
end if; 

end if; 
end if; 

end if;
tmpStr:=lpad(to_char(tmpint),4,'0');

-- dbms_output.put_line(tmpstr);

outkey := substr(to_char(myyear),3,2) || lpad(to_char(mymonth),2,'0') || lpad(to_char(myday),2,'0') || tmpStr;
select my_ziguei into tmpsign from getmykey where my_tablename=tablename;

outkey:=tmpsign ||outkey;
--dbms_output.put_line(outkey);

end;

 

时间: 2024-08-29 11:26:15

主键生成器的相关文章

hibernate中自定义主键生成器

Hibernate(目前使用的版本是3.2)中提供了多种生成主键的方式. 然而当前的这么多种生成方式未必能满足我们的要求. 比如increment,可以在一个hibernate实例的应用上很方便的时候,但是在集群的时候就不行了. 再如 identity ,sequence ,native 是数据局提供的主键生成方式,往往也不是我们需要,而且在程序跨数据库方面也体现出不足. 还有基于算法的生成方式生成出来的主键基本都是字符串的. 我们现在需要一种生成方式:使用Long作为主键类型,自动增,支持集群

JPA中的主键生成策略

Table 策略 (Table strategy) 这种策略中,持久化引擎 (persistence engine) 使用关系型数据库中的一个表 (Table) 来生成主键.这种策略可移植性比较好,因为所有的关系型数据库都支持这种策略.不同的 J2EE 应用服务器使用 不同的持久化引擎. 下面用一个例子来说明这种表生成策略的使用: 清单 1.Table 生成策略 @Entity public class PrimaryKey_Table { @TableGenerator(name = "PK_

Hibernate主键生成策略总结(这里面讲的很详细)

 Hibernate提供的主键生成策略,使我们可以在实体类的映射xml文件中设定关键字来告诉hibernate我们要使用的主键生成方式,然后hibernate会根据设定完成数据库的主键控制. 一.首先通过举例子来了解实体映射文件(*.hbm.xml)中对id生成策略配置格式     用户User的实体类User.java      [java] view plaincopyprint? package com.bjpowernode.hibernate;    import java.util.

mysql插入数据时失败但是主键id自动增加了一该如何解决

问题描述 mysql插入数据时失败但是主键id自动增加了一该如何解决 插入时因重复导致插入失败会导致id自增,第二次插入其它数据时会在会变成id加了两次的情况 解决方案 配置一下事务,如果出现异常情况则数据库进行回滚 解决方案二: 重复是指别的字段重复了是吧 解决方案三: 1.在保存前要有数据的正确性校验处理 2.插入数据操作改成存储过程,检查是否有重复 解决方案四: 建议使用事务来进行持久化的处理,这样可能就不会出错了.希望对你有用 解决方案五: 自增是这样的,,如果失败回自动加一,,但数据不

hibernate5(5)实体映射注解配置[2]主键生成策略

@GeneratedValue基本注解类型 在上一篇文章中,我们讲到了JPA使用@GeneratedValue注解来定义生成策略,而关于注解生成策略有4种基本支持类型: 1. GenerationType.TABLES 当前主键的值单独保存到一个数据库的表中 2. GenerationType.SEQUENCE 利用底层数据库提供的序列生成标识符 3. GenerationType.IDENTITY 采取数据库的自增策略 4. GenerationType.AUTO 根据不同数据库自动选择合适的

是不是用JAVA做的BS项目里 javabean就对应数据库一个表 javabean必须有一个主键ID 对应数据库里表的主键 是这样吗

问题描述 是不是用JAVA做的BS项目里javabean就对应数据库一个表javabean必须有一个主键ID对应数据库里表的主键是这样吗 解决方案 解决方案二:请教各位大牛一下是这样的吗解决方案三:没人指点下嘛解决方案四:不是必须的.主要看业务.解决方案五:引用3楼chouy的回复: 不是必须的.主要看业务. 那hibernate不是都要指定主键生成器吗解决方案六:这样做最好了,省的想太多,如果某些表的某些字段经常使用,也可以考虑抽取出来解决方案七:最好指定ID

第八章 ID主键生成策略

increment (选查找数据库中的主键生成,然后再把对象insert进去) 用于为long, short或者int类型生成 唯一标识.只有在没有其他进程往同一张表中插入数据时才能使用. 在集群下不要使用. identity   (主要用于mysql数据库) 注:对于MySql数据库使用递增序列时需要在建表时对主键指定为auto_increment属性. 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持. 返回的标识符是lon

hibernate5(13)注解映射[5]一对一共享主键关联

一对一共享主键 下面我们直接通过实例来讲解共享主键配置: 主键主控方:Article package com.zeng2.model; @Table(name = "t_article2") @Entity public class Article { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String title; @OneToOne(cascade = Casc

【HIBERNATE框架开发之四】HIBERNATE-ANNOTATION常用的注解归总&amp;&amp;ID的生成策略&amp;&amp;联合主键

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/hibernate/811.html 这篇主要讲解Hibernate中Annotation的常用注解和ID的生成策略以及联合主键三块:     首先介绍些常用的Annotation注解: 1.  当表名与类名不一致: @Table(name="数据库表名")        (javax.persistence)      如果类名与