Oracle 11g:如何生成会计科目表中的数字 查询结果

问题描述

在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;