问题描述
在oracle 11g(sql或PL / sql)中,我想生成会计科目表,例如:从级别2开始:(级别1的A / C编号为1,2,3,4,5)
如果它位于资产的头 1 中,它将生成第一个数字为 101 如果它位于责任的 2 头中,则它将生成第一个数字为 201
第3级;
如果选择了父级 101 ,则它将生成第一个帐户编号为 10101 如果选择了父级 102 ,则它将生成第一个帐户编号为 10201
以此类推。...
第4级:
如果选择了父级 10101 ,则它将生成第一个帐户编号为 10101001 如果选择了父级 10201 ,则它将生成第一个帐户编号为 10201001
以此类推...
,并且对于所有其他总帐户都是相同的(2 =责任,3 =费用,4 =收入5 =资本)
请帮助。
解决方法
下面的查询使用您定义的帐户结构生成近4000个帐户。您可以通过修改CONNECT BY LEVEL <= 5
并将5
更改为num_accts_to_generate
中的较低或较高的数量来调整生成的帐户数量。
查询
WITH
num_accts_to_generate
AS
( SELECT LEVEL AS gen_num
FROM DUAL
CONNECT BY LEVEL <= 5),level_1_accts
AS
(SELECT 1 AS account_level,'Asset' AS account_type,TO_CHAR (gen_num) AS account_number
FROM num_accts_to_generate),level_2_accts
AS
(SELECT 2 AS account_level,'Liability' AS account_type,l1.account_number
|| LPAD (ROW_NUMBER () OVER (PARTITION BY l1.account_number ORDER BY ROWNUM),2,'0') AS account_number
FROM level_1_accts l1,num_accts_to_generate),level_3_accts
AS
(SELECT 3 AS account_level,'Expense' AS account_type,l2.account_number
|| LPAD (ROW_NUMBER () OVER (PARTITION BY l2.account_number ORDER BY ROWNUM),'0') AS account_number
FROM level_2_accts l2,level_4_accts
AS
(SELECT 4 AS account_level,'Revenue' AS account_type,l3.account_number
|| LPAD (ROW_NUMBER () OVER (PARTITION BY l3.account_number ORDER BY ROWNUM),3,'0') AS account_number
FROM level_3_accts l3,level_5_accts
AS
(SELECT 5 AS account_level,'Capital' AS account_type,l4.account_number
|| LPAD (ROW_NUMBER () OVER (PARTITION BY l4.account_number ORDER BY ROWNUM),'0') AS account_number
FROM level_4_accts l4,num_accts_to_generate)
SELECT * FROM level_1_accts
UNION ALL
SELECT * FROM level_2_accts
UNION ALL
SELECT * FROM level_3_accts
UNION ALL
SELECT * FROM level_4_accts
UNION ALL
SELECT * FROM level_5_accts
ORDER BY 3;
结果
ACCOUNT_LEVEL ACCOUNT_TYPE ACCOUNT_NUMBER
________________ _______________ _________________
1 Asset 1
2 Liability 101
3 Expense 10101
4 Revenue 10101001
5 Capital 10101001001
5 Capital 10101001002
5 Capital 10101001003
5 Capital 10101001004
5 Capital 10101001005
4 Revenue 10101002
5 Capital 10101002001
5 Capital 10101002002
5 Capital 10101002003
5 Capital 10101002004
...
3,905 rows selected.
,
非常感谢 EJ Egyed 对您的帮助,我编写了下面的函数,对我来说很好用。
create or replace function get_value_no( v_value_level in number,v_value_abbreviation in varchar2,v_value_parent in number)
return number is
--
-- create trigger or function,in case of function pass following columns as parameters
-- value_leve,value_abbreviation,value_parent_acct
v_value_level number := 3;
v_value_abbreviation char(1) := 'L'; -- (A)sset (L)iability (E)xpense (R)evenue (C)apital
v_valno number;
v_parent number := 203; -- parent account which user will select
v_char varchar2(20);
begin
-- ======================
if v_value_level in (2,3) then
select max(nvl(value_no,0))
into v_valno
from value_set
where value_level = v_value_level
and value_abbreviation = v_value_abbreviation
and value_type = 'NA'
and value_parent_acct = v_value_parent;
if v_valno is null or v_valno <= 0 then
v_char := to_char(v_value_parent)||'01';
v_valno := v_char;
else
v_valno := v_valno+1;
end if;
end if;
-- ======================
if v_value_level = 4 then
select max(nvl(value_no,0))
into v_valno
from value_set
where value_level = v_value_level
and value_abbreviation = v_value_abbreviation
and value_type = 'NA'
and value_parent_acct = v_value_parent;
if v_valno is null or v_valno <= 0 then
v_char := to_char(v_value_parent)||'001';
v_valno := v_char;
else
v_valno := v_valno+1;
end if;
end if;
-- ======================
return v_valno;
--
end;