#oracle #oracle11g #numbers #account #generate
#Oracle #oracle11g #числа #Учетная запись #генерировать
Вопрос:
В oracle 11g (SQL или PL / SQL) для плана счетов я хочу генерировать такие числа, как: начните с уровня 2: (номер кондиционера уровня 1. равны 1,2,3,4,5)
если он находится в заголовке 1, который является активом, тогда он будет генерировать первое число как 101, если он находится в заголовке 2, который является пассивом, тогда он будет генерировать первое число как 201
для уровня 3;
если родительский выбран 101, то он сгенерирует первый номер a / c как 10101, если родительский выбран 102, то он сгенерирует первый номер a / c как 10201
и так далее….
для уровня 4:
если родительский элемент выбран 10101, он сгенерирует первый номер a / c как 10101001, если родительский элемент выбран 10201, он сгенерирует первый номер a / c как 10201001
и так далее…
и то же самое для всех остальных основных счетов (2 = Обязательства, 3 = Расходы, 4 = Доход, 5 = Капитал)
Пожалуйста, помогите.
Комментарии:
1. обновлено, чтобы проиллюстрировать как можно более четко.
Ответ №1:
Приведенный ниже запрос генерирует почти 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),
2,
'0') AS account_number
FROM level_2_accts l2, num_accts_to_generate),
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, num_accts_to_generate),
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),
3,
'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.
Ответ №2:
большое спасибо 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;