2

ベースライン要件は、次の形式で注文番号を作成することです。

(M)M-SSS

MM は現在の月を表し、SSSS はその月の順序シーケンスを表します。たとえば、1-002 は 1 月に送信された 2 番目の注文を表します。

TRIGGER を使用して、自動インクリメントと挿入が透過的に機能するようにしたいと思います。

残念ながら、ストアド プロシージャに触れてから長い時間が経ちました。これが postgresql への初めての試みです。正しい方向を指し示す助けがあれば大歓迎です。

更新: @peterm のコードを使用した最終的な実装は次のとおりです。

-- The trigger
CREATE TRIGGER add_order_number 
   BEFORE INSERT ON orders FOR EACH ROW
   EXECUTE PROCEDURE order_number_update();

-- The trigger function
CREATE FUNCTION order_number_update() RETURNS TRIGGER AS $$
DECLARE
    next_order TEXT;
BEGIN
    -- get the next order number
    SELECT INTO next_order CONCAT(CAST(DATE_PART('MONTH', CURRENT_DATE) AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_number), 3) AS INT), 0) + 1 AS VARCHAR(3)), 3, '0'))
    FROM orders
    WHERE CAST(LEFT(order_number, STRPOS(order_number, '-') - 1) AS INT) = DATE_PART('MONTH', CURRENT_DATE);

    -- update the field
    NEW.order_number = next_order;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

注: 更新を BEFORE INSERT トリガーとして追加することにより、通常の SERIAL または BIGSERIAL フィールドと同様に、完全に透過的で予測可能な方法で機能します。

4

1 に答える 1

2

このようなものをお探しですか?

-- Next No calculated for current month
SELECT CONCAT(CAST(DATE_PART('MONTH', CURRENT_DATE) AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_no), 4) AS INT), 0) + 1 AS VARCHAR(4)), 4, '0')) next_no
  FROM orders
 WHERE CAST(LEFT(order_no, STRPOS(order_no, '-') - 1) AS INT) = DATE_PART('MONTH', CURRENT_DATE)
;

出力:

| NEXT_NO |
-----------
|  5-0001 |

order_no= '1-0001' のレコードがあると仮定すると、

-- Next No for January
SELECT CONCAT(CAST(DATE_PART('MONTH', DATE '2013-01-01') AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_no), 4) AS INT), 0) + 1 AS VARCHAR(4)), 4, '0')) next_no
  FROM orders
 WHERE CAST(LEFT(order_no, STRPOS(order_no, '-') - 1) AS INT) = DATE_PART('MONTH', DATE '2013-01-01')
;

出力:

| NEXT_NO |
-----------
|  1-0002 |

SQLフィドル

于 2013-05-17T01:01:49.437 に答える