我想自动生成这种格式的帐单号码(INV1/23),而不使用oracle apex中的序列。请在 plsql 中编写查询。
我在此过程中使用了序列,但它对此不起作用。 它必须以表格形式显示在交互式报告上。就像当我输入有关账单的数据(例如订单号、订单日期、信用条款、信用天数和备注)时,它应该以我给定的格式自行生成。
仅生成发票号码的代码并不是解决方案。您很快就会遇到问题。
通过查看最后一个发票号码(而不是序列)来动态生成发票号码的一个问题是冲突。用户 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 表,并需要一些代码来检查您是否用完数字。
是的,您可以生成一个序列号,但是您只需要为数字中的帐单编号维护一个单独的编号列,因此,您可以根据现有表数据中的最新或最大编号添加帐单编号。你可以编写如下代码。,
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;