心想事成数据库表中的流水号,中生成流水号

初稿地址:http://www.maomao365.com/?p=7335

hbase shell命令的运用

再利用hbase 命令从前先检查一下hbase是不是运行正常化

hadoop@Master:/usr/hbase/bin$ jps
2640 HMaster
27170 NameNode
27533 SecondaryNameNode
3038 Jps
27795 TaskTracker
27351 DataNode
2574 HQuorumPeer
27618 JobTracker
2872 HRegionServer

假如运行不健康的话,关闭hbase后再也启航一下

stop-hbase.sh
start-hbase.sh

 

1.  status命令

hbase(main):008:0> status
1 servers, 0 dead, 3.0000 average load

 

2. version命令

hbase(main):007:0> version
0.94.12, r1524863, Fri Sep 20 00:25:45 UTC 2013

 

3. create 命令
成立一个名为 test 的表,这一个表唯有一个名列
cf。里头表名、列都要用单引号括起来,并以逗号隔开。

hbase(main):001:0> create 'test', 'cf'
0 row(s) in 10.3830 seconds

4. list 命令
查阅当前 HBase 中持有啥等表。

hbase(main):009:0> list
TABLE                                                                           
test                                                                            
1 row(s) in 0.3590 seconds

 

5. put 命令
接纳 put
命令向表中插入数据,参数分别为表名、行名、列名和值,其中列名前须要列族最为前缀,时间戳由系统自动生成。
格式: put 表名,行名,列名([997755.com澳门葡京,列族:列名]),值
例子:
进入一行数据,行名称为“row1”,列族“cf”的列名为”(空字符串)”,值位 value1。
本人那边插入3条记下

hbase(main):003:0> put 'test', 'row1', 'cf:a', 'value1'
0 row(s) in 0.2350 seconds

hbase(main):004:0> put 'test', 'row2', 'cf:b', 'value2'
0 row(s) in 0.0350 seconds

hbase(main):005:0> put 'test', 'row3', 'cf:c', 'value3'
0 row(s) in 0.0040 seconds

6. describe 命令
查看表“test”的构造。

hbase(main):010:0> describe 'test'
DESCRIPTION                                          ENABLED                    
 'test', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE true                       
 ', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0',                            
  VERSIONS => '3', COMPRESSION => 'NONE', MIN_VERSIO                            
 NS => '0', TTL => '2147483647', KEEP_DELETED_CELLS                             
 => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'fal                            
 se', ENCODE_ON_DISK => 'true', BLOCKCACHE => 'true'                            
 }                                                                              
1 row(s) in 1.6630 seconds

7.get 命令
a.查看表“test”中的行“row2”的连锁数据。

hbase(main):011:0> get 'test','row2'
COLUMN                CELL                                                      
 cf:b                 timestamp=1381568161926, value=value2                     
1 row(s) in 0.4500 seconds

b.查看表“test”中行“row2”列“cf :b”的值。

hbase(main):012:0> get 'test','row2', 'cf:b'
COLUMN                CELL                                                      
 cf:b                 timestamp=1381568161926, value=value2                     
1 row(s) in 0.3090 seconds

或者

hbase(main):012:0> get 'test', 'row2', {COLUMN=>'cf:b'}
hbase(main):012:0> get 'test', 'row2', {COLUMNS=>'cf:b'}

备考:COLUMN 和 COLUMNS 是例外的,scan 操作中的 COLUMNS 指定的是表的列族,
get操作中的 COLUMN 指定的是一定的列,COLUMNS
的值实质上为“列族:列修饰符”。COLUMN 和
COLUMNS 必须为大写。

8. scan 命令
a. 查看表“test”中的所有数据。

hbase(main):006:0> scan 'test'
ROW                   COLUMN+CELL                                               
 row1                 column=cf:a, timestamp=1381568140492, value=value1        
 row2                 column=cf:b, timestamp=1381568161926, value=value2        
 row3                 column=cf:c, timestamp=1381568176693, value=value3        
3 row(s) in 0.0770 seconds

注意:
scan 命令能够指定 startrow,stoprow 来 scan 多个 row。
例如:

scan 'user_test',{COLUMNS =>'info:username',LIMIT =>10, STARTROW => 'test', STOPROW=>'test2'}

b.查看表“scores”中列族“course”的富有数据。

hbase(main):012:0> scan  'scores', {COLUMN => 'grad'}
hbase(main):012:0> scan  'scores', {COLUMN=>'course:math'}
hbase(main):012:0> scan  'scores', {COLUMNS => 'course'}
hbase(main):012:0> scan  'scores', {COLUMNS => 'course'}

9.count
命令——计算出表中有稍许条记下

hbase(main):013:0> count 'test'
3 row(s) in 1.6530 seconds

10. exists 命令——查看表是或不是存在

hbase(main):014:0> exists 'test'
Table test does exist                                                           
0 row(s) in 1.1620 seconds

11. incr 命令

给‘test’那些列扩充 uid
字段,并运用counter完结递增
接连实施incr以上,COUNTER VALUE 的值会递增,通过get_counter

hbase(main):010:0> incr 'test', 'row2', 'uid', 2
COUNTER VALUE = 2

hbase(main):011:0> incr 'test', 'row2', 'uid', 3
COUNTER VALUE = 5

查看表可以看出:

hbase(main):012:0> scan 'test'
ROW                   COLUMN+CELL                                               
 row1                 column=uid:1, timestamp=1381571789416, value=buym:1       
 row2                 column=uid:, timestamp=1381572436088, value=\x00\x00\x00\x
                      00\x00\x00\x00\x05                                        
 row2                 column=uid:2, timestamp=1381571805008, value=buym:20      
2 row(s) in 0.0790 seconds

12. delete 命令
删除表“test”中行为“row3”, 列族“cf”中的“c”。

hbase(main):015:0> delete 'test','row3','cf:c'
0 row(s) in 0.4640 seconds

 

13. truncate
下令——将表删除后再另行创制

hbase(main):018:0> truncate 'test'
Truncating 'test' table (it may take a while):
 - Disabling table...
 - Dropping table...
 - Creating table...
0 row(s) in 5.6480 seconds

 

14. disbale、drop 命令
透过“disable”和“drop”命令删除“test”表。

hbase(main):001:0> disable 'test'
hbase(main):003:0> drop 'test'
0 row(s) in 3.9310 seconds

997755.com澳门葡京 1

 

思路:

完成的流水号样式(字符+日期+流水号)如下

 

 通过一个水流号表,记录当前最大的流水号,以便下次取用。每一次取号时,将流水号表更新成大的。

997755.com澳门葡京 2

摘要:

论及的表:

流水号.png

 

   流水号表hp_no:  

诚如自己在写小demo的时候,都是使用的纯数字自增(1,2,3……)这种。比较而言,流水号方式的看起来更专业,而且可以从流水号中了然多少的丰盛时间及顺序,当然,是或不是望着更有逼格。

心想事成数据库表中的流水号,中生成流水号。 
 数据表中,有一列是活动流水号,由于各个操作尤其原因(或者插入战败),此列数据会变的不总是,下文将讲述使用sql脚本的点子获取数据表中的多寡是不是三番五次的主意分享,如下所示:

字段 类型
TYPE_NAME VARCHAR2(100)
START_NO VARCHAR2(100)
CURRENT_NO VARCHAR2(100)

时下自己使用的不二法门是,利用存储进程来兑现(可能还有好多主意),因为那种一般是在插入数据的时候利用,所以把插入数据的操作也位于了仓储进程。若是近年来不明了存储进度这么些概念的小白,可以看我那篇的介绍第四次接触存储进程

 

 代码:

<h3>分析</h3>
该字段由三有些组成:QQ字符 + 201706(年月,即眼先天期)+
0001(流水号,自动增长)

   实验环境:sqlserver 2008 R2  

1)通过函数得到最大值。 有三个参数,

  1. QQ字符不用管
  2. 201706,当然是先取得到系统当下的小时,然后得到对应的6位数值
  3. 流水号,为了确保主键不重复,同一时间内,这有些流水号应该是不一致的,所以流水号从
    0000~9999
    ,即同一段时间最多会有一万个不等的流水号。(近年来不考虑9999加1之后的情景)

  首个参数是项目,便于得到分化的流水号。

<h3>实现</h3>
先是创制一个test表,方便讲解

 

  首个参数是前缀,用于在流水号前面放置特其余字符。

create table test(
     pk_id varchar(12) not null,
     name varchar(10) null
)

例:获取表test中keyId是不是为总是的多寡

  第一个参数是生成的流水号长度。

贯彻201706的前一步(得到当前的时日)

 

 

CONVERT(varchar(8), GETDATE(), 112)  --获取对应格式(20170601)的当前系统时间

心想事成思路:

997755.com澳门葡京 3997755.com澳门葡京 4代码

实现201706,同时把收获的值赋值给一个变量(为了代码看起来清晰)

 

CREATE OR REPLACE FUNCTION Hp_Test_GetNo(
   P_TYPE_NAME   IN   VARCHAR2 DEFAULT ”,  –类型 参数1
   P_START_NO    IN   VARCHAR2,  –前缀 参数2
   P_LENGTH      IN   NUMBER    –得到流水号长度 参数3
)
   RETURN VARCHAR2      –重临类型
IS
   V_RESULT       VARCHAR2 (100) := ”;   –结果   变量1
   V_CURRENT_NO   VARCHAR2 (100) := ”;  –当前值  变量2
   V_NUM          NUMBER         := 0;  –补值    变量3
   V_START_NO   VARCHAR2(100);    –前缀    变量4
   V_ROWID        VARCHAR2 (100);    –要更新行的RowID  变量4
BEGIN
   V_START_NO :=P_START_NO;  –参数值赋给变量

declare @dateStr varchar(6)  --定义变量
----使用substring()方法截取前6位,同时赋值变量
select @dateStr = (select SUBSTRING((Select CONVERT(varchar(8), GETDATE(), 112)),1,6)) 

 1.采用row_number 对表test重新生成流水号

   SELECT COUNT (*)
     INTO V_NUM
     FROM HP_NO
    WHERE TYPE_NAME = P_TYPE_NAME AND START_NO = P_START_NO;    –得到类型与前缀相同值的数目,紧要用以判断是或不是爆发过流水号

贯彻0001的前一步(那里假诺表中早就存在一条数据,那么它的4位流水号应该是0000,完整代码部分中会考虑第一条数据的标题。得到近年来生产的4位流水号,新的流水号是在此基础上收获)

 

–判断是或不是有资料 没有则发出开首值插入库中
   IF V_NUM = 0  –没有记录过时
   THEN
      V_CURRENT_NO := LPAD (‘1’, P_LENGTH, ‘0’);  –得到P_length长的0001流水号
      V_RESULT := V_CURRENT_NO;  –将前缀与流水号相连起来

----拿到上一个最近生成的pk_id
select top 1 pk_id from table test order by pk_id desc 

 2.施用with as (cte)表明式将再也生成流水号的表放入临时表

      INSERT INTO HP_NO(TYPE_NAME, START_NO, CURRENT_NO)
           VALUES (P_TYPE_NAME, P_START_NO, V_CURRENT_NO);  –将新的最大值记录下来
   ELSE  
      SELECT ROWID, CURRENT_NO + 1
      INTO V_ROWID, V_CURRENT_NO
        FROM HP_NO
       WHERE TYPE_NAME = P_TYPE_NAME AND START_NO = P_START_NO; –得到最大值加1

实现0001,那只是开始

 

      V_CURRENT_NO := LPAD (V_CURRENT_NO, P_LENGTH, ‘0’);     
      
      
      UPDATE HP_NO
         SET CURRENT_NO = V_CURRENT_NO
       WHERE ROWID = V_ROWID;    –更新最大值
   END IF;  

declare @maxNo varchar(4)  ----定义变量
----把上诉得到的最近生产的pk_id,通过substring()方法截取最后的4位流水号,然后对其加1
select @maxNo=(Select SUBSTRING( (select top 1 pk_id from test order by pk_id desc),9,4)+1);

 3.对临时表自身举行左连接(前一行和后一行互补),然后相比行中两张表的keyId 是还是不是离开1,

   IF V_START_NO IS NULL OR V_START_NO=” THEN
      V_RESULT := V_CURRENT_NO;
   ELSE
      V_RESULT :=V_START_NO || V_CURRENT_NO;
   END IF;
   
   RETURN V_RESULT;
END;

即便新生成了一个流水号,可是无法一贯动用,因为一旦@maxNo的值不是4位数,那么就会扰乱pk_id的队形,所以必要开展判断

 

使用存储进度调用函数的办法:

if (@maxNo < 10) begin
    set @maxNo = '000' + @maxNo; --如果是1位数的话,需要在前面加3个0,补够4位
end 
else if (@maxNo < 100) begin
    set @maxNo = '00' + @maxNo; --如果是2位数的话,需要在前面加2个0,补够4位
end
else if (@maxNo < 1000) begin
    set @maxNo = '0' + @maxNo; --如果是3位数的话,需要在前面加1个0,补够4位
end

   要是距离1,则象征延续数据行,反之为非连续行数据

997755.com澳门葡京 5997755.com澳门葡京 6代码

迄今截止,分割的各种部分都落到实处了。为了有利于插入操作,把所有值结合起来,用一个新的变量来储存

create table test 

(keyId int,info varchar(60))

go

insert into test(keyId,info)values

(1,'maomao365.com'),(2,N'连续数判断'),

(4,N'blog教程'),(5,'maomao'),

(8,'test'),(9,'info')

;

with  tmp as 

 (select  ROW_NUMBER() over (order by keyId asc ) as keyIdNew,

* from test  ) 

select a.keyIdNew,

a.keyId,a.info ,

 case  when ISNULL(a.keyId,0)-1 = b.keyId 

              or b.keyId is null  then '连续'

       else '不连续'

 end as '连续标志'

 from tmp a 

left join tmp b on a.keyIdNew = b.keyIdNew+1

;

go

truncate table test 

drop     table test 

–调用function存储进程
CREATE OR REPLACE PROCEDURE Hp_Pro_GetTestNo
(
      v_FirstLetter in varchar2,
      v_Result out  varchar2
)
   IS
      v_FirstValue varchar2(30);
      v_SystDate varchar2(30);
BEGIN
     select to_char(sysdate,’yyyymm’) into v_SystDate from dual;
     v_FirstValue:=(v_FirstLetter || v_SystDate);
     v_Result:=hp_test_getno(‘HpTest’ ,v_FirstValue,4);
END;

declare @result nvarchar(12)--共计12位,前两位为QQ,中间6位是年月,最后4位是流水号
----把之前得到的@dateStr和maxNo加上,QQ字符直接加上即可
select @result=(Select 'QQ' + @dateStr + @maxNo);

 997755.com澳门葡京 7

结果:

末段,把要求插入表中的数量作为参数传递到存储进度中,在储存进程中推行插入操作

 

   调用存储进程Hp_Pro_GetTestNo(‘hp’,4);

@name -- 需要插入test表中的值
insert into test(pk_id,name) values(@result,@name)

  结果为:hp2010020001

那就是一体化的进程,在实施插入数据的操作时,把除了pk_id之外的字段当做参数传入到存储进度中,在蕴藏进程中实施insert操作即可

 

总体的储存进程代码如下

其余思考

USE [Test] ----Test是test表所在的数据库名
GO
/****** Object:  StoredProcedure [dbo].[AddData]    Script Date: 06/01/2017 18:51:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[AddData]  
    @name varchar(10)  ----参数,用于接收传入的name值
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    declare @dateStr varchar(6),  ----定义变量,用于存储6位数的时间
    @maxNo varchar(4), ----定义变量,用于存储4位流水号
    @result varchar(12) -----定义变量,用于存储新生成的pk_id

    ----获取到系统当前时间,并截取符合条件的6位,同时赋值给@dateStr
    select @dateStr = (select SUBSTRING((Select CONVERT(varchar(8), GETDATE(), 112)),1,6))

    ----先判断是否第一次向test表中插入数据(即当前表中是否存在数据)
    if exists (select * from test) begin
        ----获取数据表中最近产生的一个pk_id,并截取最后4位流水号,对4位流水号进行加1,最后赋值给@maxNo
        select @maxNo=(Select SUBSTRING( (select top 1 pk_id from test order by pk_id desc),9,4)+1);

        ----对上诉的@maxNo做判断,确保流水号一定是4位,不够的在前面补0
        if (@maxNo < 10) begin
            set @maxNo = '000' + @maxNo; --如果是1位数的话,需要在前面加3个0,补够4位
        end 
        else if (@maxNo < 100) begin
            set @maxNo = '00' + @maxNo; --如果是2位数的话,需要在前面加2个0,补够4位
        end
        else if (@maxNo < 1000) begin
            set @maxNo = '0' + @maxNo; --如果是3位数的话,需要在前面加1个0,补够4位
        end

        ----将上诉结果合成一个新的pk_id
        select @result=(Select 'QQ' + @dateStr + @maxNo)
    end 
    else
       ----如实当前插入的数据时第一条数据,那么直接把4位流水号设为0000
       select @result = 'QQ' + @dateStr + '0000'

    ----将数据插入到test表中
    insert into test(pk_id,name) values(@result,@name);
END

一、新增时绝不出示流水号,如得到得到三番五次流水号

 方法:

  拔取流水号子表,此表用于保存没有用过的流水号。当用户取号时,首选判断子表是不是包蕴流水号,当有时,取出一个,并剔除此个(幸免别其它用户取用);否则调用主表获得新流水号。

当插入战败则将眼前流水号保存到流水号子表中,供下次取用。

当删除时,将眼前流水号保存到流水号子表中,供下次取用。

二、新增时须突显流水号,如得到得到再而三流水号

方法:

  选择流水号子表,此表用于保存没有用过的流水号。当用户取号时,首选判断子表是或不是含有流水号,当有时,取出一个,并剔除此个(防止别其余用户取用);否则调用
主表得到新流水号。

当用户不保留或插队败北则将眼前流水号保存到流水号子表中,供下次取用。

当删除时,将近日流水号保存到流水号子表中,供 下次取用。

 

其他思考的代码我从不写,有趣味的心上人可以协调写。

 

 

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website