Oracle存储过程生成序列号?

时间:2012-05-18 04:32:44

标签: oracle stored-procedures

我有一个员工,产品和产品里程表,如下所示

enter image description here

每位员工都有一个独特的emp_code,具体取决于他有权访问的产品。

每个产品的标识符都有唯一的前缀。

我需要为每个产品生成一个唯一的字母数字标识符,并将其分配给员工。

此产品标识符长度为9个字符,包括前缀。

里程表会存储分配给该特定产品中员工的最后一个emp_code。

如何编写存储过程以根据产品为系统中添加的每个新员工生成这些字母数字emp_codes?

请帮忙。

编辑1:

在里程表表中只是一个小的修正,我们可能不需要将里程表存储为A00000001。相反,我们只能存储00000001,然后附加前缀。

编辑2:

这是我到目前为止所做的。

create or replace PROCEDURE SP_GEN_NEXT_DUMMY_DB_PRISM_ID
(
  in_product_id number,
  db_prism_id out varchar2
)
AS
BEGIN

  UPDATE BI_DB_PRISM_ID_ODOMETER
  SET DB_PRISM_ID =  DB_PRISM_ID + 1
  WHERE 
    PRODUCT_ID = in_product_id; 

  SELECT to_char(db_prism_id, 'FM00000000') into db_prism_id FROM     BI_DB_PRISM_ID_ODOMETER WHERE PRODUCT_ID = in_product_id; 

END;

但是如何确保它在事务中运行,以及如何将产品前缀附加到生成的数字上。

3 个答案:

答案 0 :(得分:3)

我有两个选择:

  1. 为每个产品创建一个Oracle序列,可能采用某种维护程序来检测新产品并动态创建序列。

  2. 滚动您自己的序列代码。将最后一个值存储在Product表中。编写一个为给定产品生成新值的过程。该过程将首先在product表上获得行锁(这样您不会同时获得两个会话获得相同的值),推进该值,并将新值写入Product表。您需要将此过程作为自治事务(否则,如果会话未提交或立即回滚,则其他会话将等待。)

  3. #1的一个优点是它是最快的。

    #1的缺点是您必须运行动​​态DDL,并且在尝试为其插入里程表记录之前,您必须确保已经运行了产品的DDL。如果删除产品,您可能还需要考虑是否删除序列。

    #1的另一个缺点是你只能用动态SQL获取序列值(你必须在运行时确定序列的名称)。

    #2的一个缺点是,对于允许并发DML的系统来说,很容易出错。您需要确保正确的逻辑,并在高并发负载下测试它。此外,#2的性能会比#1差,因为它会序列化每个产品的访问权限。

    修改

      

    “但我怎样才能确保它在交易中运行,以及如何运作   我将产品前缀附加到生成的数字上。“

    Oracle中的事务是自动进行的。但是,在这种情况下,您想要的是autonomous transaction

    使用字符串连接功能完成附加产品前缀 - 例如||

答案 1 :(得分:1)

这似乎是你在这里对数据模型进行非规范化。

里程表与产品表的比例为1:1,里程表值也取决于当前分配给该产品的员工人数。

emp_code序列号可以从员工ID和产品表中派生。可以说,标识符前缀也可以从产品ID中推断出来,因此实际上您的架构中有冗余列和冗余表。

你确定你真的需要它们吗?

答案 2 :(得分:0)

也许我在这里遗漏了一些东西,如果是这样,请接受我的道歉。

在我看来,里程表仅仅是一个员工可以访问每种产品的计数器。

如果是这种情况,为什么不完全摆脱表(和EMP_CODE列)和#34; build"一个或多个视图中的信息?

的Alessandro

PS:看起来我发布了David Aldridge的相同建议。对不起,感到困惑。