【问题标题】:Autoincrement dependent of other field依赖于其他字段的自动增量
【发布时间】:2012-09-24 08:50:58
【问题描述】:

获得依赖于其他字段的自动增量“计数器”的最佳方法是什么?

想象一下这张桌子

CUSTOMER - COUNTER
1 - 1
1 - 2
1 - 3
2 - 1
2 - 2

我需要 Counter 为每个客户添加的每条记录增加 1。

问候。

【问题讨论】:

    标签: stored-procedures firebird


    【解决方案1】:

    为每个客户创建额外的表格来存放柜台:

    CREATE TABLE customer_counter
    (
      customer_id  INTEGER NOT NULL,
      counter      INTEGER NOT NULL,
    
      PRIMARY KEY (customer_id)
    )
    

    使用以下程序获取给定客户的下一个柜台号码:

    CREATE PROCEDURE get_customer_counter (customer_id INTEGER)
      RETURNS (counter INTEGER)
    AS
    BEGIN
      SELECT SUM(counter) FROM customer_counter
      WHERE customer_id = :customer_id
      INTO :counter;
    
      counter = COALESCE(:counter, 0);
    
      EXECUTE STATEMENT 
        'INSERT INTO customer_counter (customer_id, counter) ' ||
        'VALUES (' || :customer_id || ', 1)'
        WITH AUTONOMOUS TRANSACTION;
    END
    

    了解我们如何使用 sum 和插入 delta 值而不是更新单个记录。因此我们可以防止死锁。

    我们需要定期通过将增量记录合并为一个总值来清除计数器表:

    CREATE TRIGGER on_disconnect_database
      ACTIVE
      ON DISCONNECT
    AS
      DECLARE VARIABLE sm          INTEGER;
      DECLARE VARIABLE cnt         INTEGER;
      DECLARE VARIABLE customer_id INTEGER;
    BEGIN
      FOR
        SELECT customer_id, SUM(counter), COUNT(counter)
        FROM customer_counter
        GROUP BY customer_id
        INTO :customer_id, :sm, :cnt
      DO BEGIN
        IF (:cnt > 1) THEN
        BEGIN
          DELETE FROM customer_counter WHERE customer_id = :customer_id;
          INSERT INTO customer_counter (customer_id, counter)
            VALUES (:customer_id, :sm);
          WHEN ANY DO
          BEGIN
          END
        END
      END
    END
    

    【讨论】:

    • 我认为我没有正确解释,抱歉,但您的回答将帮助我解决另一件事。想法是,如果我在表中添加一条新记录,对于客户 1,计数器值必须为 4,但如果是针对客户 2,则计数器值必须为 3。想法是例如分配一个订单字段到账单细节的记录。账单的所有详细信息都在一个表中,并且计数器值必须为每个 ID 账单组自动递增。我希望我现在解释得更好。谢谢。
    【解决方案2】:

    很难真正说出你到底想要什么,但我假设你想遍历每个 X 字段和它的 Y 子字段,将其用作计数器或其他任何东西。

    <?php
    $x = array("customer1","customer2","customer3");
    $y = array("name","address","phone");
    
    $counter;
    
    foreach($x as $eachX):
        $counter  = 1;
        foreach($y as $eachY):
            //do stuff here
            $counter++;
        endforeach;
    endforeach;
    ?>
    

    【讨论】:

      【解决方案3】:

      我觉得这个存储过程就可以了!

      create procedure New_Procedure
      returns (
      o_customer integer,
      o_counter integer)
      as
      
      declare variable v_oldcostomer integer;
      begin
      
      for select customer
       from customers
       order by 1
       into o_customer
       do begin
       if (v_oldcostomer is null or (v_oldcostomer is not null and v_oldcostomer <> o_customer) ) then
          o_counter = 0;
      
       o_counter = o_counter + 1;
       v_oldcostomer = o_customer;
       suspend;
       end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 2014-12-01
        • 2018-04-17
        • 1970-01-01
        • 2016-06-18
        • 1970-01-01
        相关资源
        最近更新 更多