我想自动生成这种格式的账单编号(INV1/23)并且它必须以1递增

问题描述 投票:0回答:2

我想自动生成这种格式的帐单号码(INV1/23),而不使用oracle apex中的序列。请在 plsql 中编写查询。

我在此过程中使用了序列,但它对此不起作用。 它必须以表格形式显示在交互式报告上。就像当我输入有关账单的数据(例如订单号、订单日期、信用条款、信用天数和备注)时,它应该以我给定的格式自行生成。

oracle-apex increment auto-generate
2个回答
2
投票

仅生成发票号码的代码并不是解决方案。您很快就会遇到问题。

通过查看最后一个发票号码(而不是序列)来动态生成发票号码的一个问题是冲突。用户 1 打开表单,代码检查最后一个发票号码 (INV1/23) 并生成一个新发票号码 - 比如说 INV2/23。现在,用户 2 在另一个会话中打开该表单。该代码将生成相同的 INV2/23,因为最后保存的值是 INV1/23,然后当第二次使用保存时...将出现唯一约束违规。 我的建议是创建一个表,其中包含您想要的格式的生成发票号码(您的要求太模糊,无法为您提供代码),并使用一些代码来决定下一个要提取的号码,因此每个值仅使用一次。这还允许您重复使用孤立值(例如,当使用发票编号但随后交易被取消时)。我建议观看 Connor 的this 视频,其中解释了我刚才描述的解决方案。它用于序列,但您可以对发票编号使用相同的逻辑。

这是代码。

create table invoice_numbers (
    id                             number generated by default on null as identity 
                                   constraint invoice_numbers_id_pk primary key,
    seq                            number,
    invoice_year                   number,
    state                          varchar2(10 char),
    invoice_num                    as ('INV'||seq||'/'||SUBSTR(invoice_year,3,2))

)
;

DECLARE
BEGIN
  FOR i IN 1..100 LOOP
    INSERT INTO invoice_numbers (seq,invoice_year, state) 
      values (i,2023,'free');
  END LOOP;
END;
/

select * from invoice_numbers;

CREATE OR REPLACE FUNCTION next_invoice_number (year_i NUMBER) RETURN VARCHAR2
IS
  l_invoice_num VARCHAR2(100);
  l_id NUMBER;
  CURSOR next_invoice_num IS
    SELECT invoice_num, id 
      FROM invoice_numbers
     WHERE invoice_year = year_i
       AND state = 'free'
       ORDER BY seq 
       FOR UPDATE SKIP LOCKED;       
BEGIN
  OPEN next_invoice_num;
  FETCH next_invoice_num INTO l_invoice_num, l_id;
  CLOSE next_invoice_num;
  UPDATE invoice_numbers SET state = 'used' WHERE id = l_id;
  RETURN l_invoice_num;
END;
/

然后在您的 apex 表单中,使用源(pl/sql 表达式)对发票编号创建提交前计算

next_invoice_number(extract (year from sysdate))

请注意,您应该只在提交之前计算发票号码 - 如果在表格上完成,则发票号码将被标记为“已使用”。因此,如果用户随后关闭屏幕而不保存发票,您将丢失该号码。

请注意,您每年都需要一些代码来填充invoice_numbers 表,并需要一些代码来检查您是否用完数字。


0
投票

是的,您可以生成一个序列号,但是您只需要为数字中的帐单编号维护一个单独的编号列,因此,您可以根据现有表数据中的最新或最大编号添加帐单编号。你可以编写如下代码。,

declare
v_bill_number number;
v_bill_no varchar2(100);
begin
select max(bill_number) into v_bill_number from bill_master;
v_bill_no := 'INV'||NVL(v_bill_number,1)||TO_CHAR(SYSDATE,'YY');
return v_bill_no;
end;
© www.soinside.com 2019 - 2024. All rights reserved.