- èªåã³ã³ãã€ã«ãã°
- ãã©ã¡ãŒã¿ã䜿çšããŠãã¥ãŒãäœæããå Žåã®å¯ŸåŠæ¹æ³
- ã¯ãšãªã§ã®åççµ±èšã®äœ¿çš
- ããŒã¿ããŒã¹ãªã³ã¯ãä»ããŠããŒã¿ãæ¿å ¥ãããšãã«ã¯ãšãªãã©ã³ãä¿åããæ¹æ³
- 䞊åã»ãã·ã§ã³ã§ã®ããã·ãŒãžã£ã®å®è¡
- æ®ãç©ãåŒã£åŒµã
- è€æ°ã®ã¹ããŒãªãŒã1ã€ã«çµã¿åããã
- ããŒãã©ã€ã¶ãŒ
- SVG圢åŒã§ã®ã¬ã³ããªã³ã°
- Oracleã¡ã¿ããŒã¿æ€çŽ¢ã¢ããªã±ãŒã·ã§ã³
èªåã³ã³ãã€ã«ãã°
äžéšã®OracleããŒã¿ããŒã¹ã§ã¯ãSberbankã«ã¯ããµãŒããŒãªããžã§ã¯ãã®ã³ãŒãã§èª°ãããã€ãäœãå€æŽãããããèšæ¶ããã³ã³ãã€ã«ããªã¬ãŒããããŸãããããã£ãŠãå€æŽã®äœæè ã¯ãã³ã³ãã€ã«ãã°ããŒãã«ãã確èªã§ããŸããããŒãžã§ã³å¶åŸ¡ã·ã¹ãã ãèªåçã«å®è£ ãããŸãããããã«ãããããã°ã©ããŒãå€æŽãGitã«éä¿¡ããã®ãå¿ããå Žåããã®ã¡ã«ããºã ã¯ãããžããŸãããã®ãããªèªåã³ã³ãã€ã«ãã°ã·ã¹ãã ã®å®è£ äŸã説æããŸããããddl_changes_logããŒãã«ã®åœ¢åŒã§ãã°ã«æžã蟌ãã³ã³ãã€ã«ããªã¬ãŒã®ç°¡ç¥åãããããŒãžã§ã³ã®1ã€ã¯ã次ã®ããã«ãªããŸãã
create table DDL_CHANGES_LOG
(
id INTEGER,
change_date DATE,
sid VARCHAR2(100),
schemaname VARCHAR2(30),
machine VARCHAR2(100),
program VARCHAR2(100),
osuser VARCHAR2(100),
obj_owner VARCHAR2(30),
obj_type VARCHAR2(30),
obj_name VARCHAR2(30),
previous_version CLOB,
changes_script CLOB
);
create or replace trigger trig_audit_ddl_trg
before ddl on database
declare
v_sysdate date;
v_valid number;
v_previous_obj_owner varchar2(30) := '';
v_previous_obj_type varchar2(30) := '';
v_previous_obj_name varchar2(30) := '';
v_previous_change_date date;
v_lob_loc_old clob := '';
v_lob_loc_new clob := '';
v_n number;
v_sql_text ora_name_list_t;
v_sid varchar2(100) := '';
v_schemaname varchar2(30) := '';
v_machine varchar2(100) := '';
v_program varchar2(100) := '';
v_osuser varchar2(100) := '';
begin
v_sysdate := sysdate;
-- find whether compiled object already presents and is valid
select count(*)
into v_valid
from sys.dba_objects
where owner = ora_dict_obj_owner
and object_type = ora_dict_obj_type
and object_name = ora_dict_obj_name
and status = 'VALID'
and owner not in ('SYS', 'SPOT', 'WMSYS', 'XDB', 'SYSTEM')
and object_type in ('TRIGGER', 'PROCEDURE', 'FUNCTION', 'PACKAGE', 'PACKAGE BODY', 'VIEW');
-- find information about previous compiled object
select max(obj_owner) keep(dense_rank last order by id),
max(obj_type) keep(dense_rank last order by id),
max(obj_name) keep(dense_rank last order by id),
max(change_date) keep(dense_rank last order by id)
into v_previous_obj_owner, v_previous_obj_type, v_previous_obj_name, v_previous_change_date
from ddl_changes_log;
-- if compile valid object or compile invalid package body broken by previous compilation of package then log it
if (v_valid = 1 or v_previous_obj_owner = ora_dict_obj_owner and
(v_previous_obj_type = 'PACKAGE' and ora_dict_obj_type = 'PACKAGE BODY' or
v_previous_obj_type = 'PACKAGE BODY' and ora_dict_obj_type = 'PACKAGE') and
v_previous_obj_name = ora_dict_obj_name and
v_sysdate - v_previous_change_date <= 1 / 24 / 60 / 2) and
ora_sysevent in ('CREATE', 'ALTER') then
-- store previous version of object (before compilation) from dba_source or dba_views in v_lob_loc_old
if ora_dict_obj_type <> 'VIEW' then
for z in (select substr(text, 1, length(text) - 1) || chr(13) || chr(10) as text
from sys.dba_source
where owner = ora_dict_obj_owner
and type = ora_dict_obj_type
and name = ora_dict_obj_name
order by line) loop
v_lob_loc_old := v_lob_loc_old || z.text;
end loop;
else
select sys.dbms_metadata_util.long2clob(v.textlength, 'SYS.VIEW$', 'TEXT', v.rowid) into v_lob_loc_old
from sys."_CURRENT_EDITION_OBJ" o, sys.view$ v, sys.user$ u
where o.obj# = v.obj#
and o.owner# = u.user#
and u.name = ora_dict_obj_owner
and o.name = ora_dict_obj_name;
end if;
-- store new version of object (after compilation) from v_sql_text in v_lob_loc_new
v_n := ora_sql_txt(v_sql_text);
for i in 1 .. v_n loop
v_lob_loc_new := v_lob_loc_new || replace(v_sql_text(i), chr(10), chr(13) || chr(10));
end loop;
-- find information about session that changed this object
select max(to_char(sid)), max(schemaname), max(machine), max(program), max(osuser)
into v_sid, v_schemaname, v_machine, v_program, v_osuser
from v$session
where audsid = userenv('sessionid');
-- store changes in ddl_changes_log
insert into ddl_changes_log
(id, change_date, sid, schemaname, machine, program, osuser,
obj_owner, obj_type, obj_name, previous_version, changes_script)
values
(seq_ddl_changes_log.nextval, v_sysdate, v_sid, v_schemaname, v_machine, v_program, v_osuser,
ora_dict_obj_owner, ora_dict_obj_type, ora_dict_obj_name, v_lob_loc_old, v_lob_loc_new);
end if;
exception
when others then
null;
end;
ãã®ããªã¬ãŒã§ã¯ãã³ã³ãã€ã«ããããªããžã§ã¯ãã®ååãšæ°ããã³ã³ãã³ããååŸãããããŒã¿ãã£ã¯ã·ã§ããªãã以åã®ã³ã³ãã³ããè£è¶³ãããå€æŽãã°ã«æžã蟌ãŸããŸãã
ãã©ã¡ãŒã¿ã䜿çšããŠãã¥ãŒãäœæããå Žåã®å¯ŸåŠæ¹æ³
ãã®ãããªèŠæã¯ãOracleã®éçºè ããã蚪ããããšãã§ããŸãããã©ã¡ãŒã¿ã䜿çšããŠããã·ãŒãžã£ãŸãã¯é¢æ°ãäœæã§ããã®ã«ãèšç®ã«äœ¿çšã§ããå ¥åãã©ã¡ãŒã¿ãå«ããã¥ãŒããªãã®ã¯ãªãã§ããïŒãªã©ã¯ã«ã«ã¯ãç§ãã¡ã®æèŠã§ã¯ããã®æ¬ ããŠããæŠå¿µã眮ãæãããã®ããããŸãã
äŸãèŠãŠã¿ãŸããããæ¯æ¥ã®éšéå¥ã®å£²äžé«ã®è¡šããããšããŸãã
create table DIVISION_SALES
(
division_id INTEGER,
dt DATE,
sales_amt NUMBER
);
ãã®ã¯ãšãªã¯ã2æ¥éã®éšéå¥ã®å£²äžãæ¯èŒããŸãããã®å Žåã2020幎4æ30æ¥ãš2020幎9æ11æ¥ã§ãã
select t1.division_id,
t1.dt dt1,
t2.dt dt2,
t1.sales_amt sales_amt1,
t2.sales_amt sales_amt2
from (select dt, division_id, sales_amt
from division_sales
where dt = to_date('30.04.2020', 'dd.mm.yyyy')) t1,
(select dt, division_id, sales_amt
from division_sales
where dt = to_date('11.09.2020', 'dd.mm.yyyy')) t2
where t1.division_id = t2.division_id;
ãã®ãããªèŠæããŸãšããããã«æžããããšæããŸããæ¥ä»ããã©ã¡ãŒã¿ãšããŠæž¡ãããã®ã§ããããã ããæ§æã§ã¯ããã¯èš±å¯ãããŠããŸããã
create or replace view vw_division_sales_report(in_dt1 date, in_dt2 date) as
select t1.division_id,
t1.dt dt1,
t2.dt dt2,
t1.sales_amt sales_amt1,
t2.sales_amt sales_amt2
from (select dt, division_id, sales_amt
from division_sales
where dt = in_dt1) t1,
(select dt, division_id, sales_amt
from division_sales
where dt = in_dt2) t2
where t1.division_id = t2.division_id;
ãã®åé¿çããå§ãããŸãããã®ãã¥ãŒããç·ã®åãäœæããŠã¿ãŸãããã
create type t_division_sales_report as object
(
division_id INTEGER,
dt1 DATE,
dt2 DATE,
sales_amt1 NUMBER,
sales_amt2 NUMBER
);
ãããŠããã®ãããªæååããããŒãã«ã®åãäœæããŸãã
create type t_division_sales_report_table as table of t_division_sales_report;
ãã¥ãŒã®ä»£ããã«ãæ¥ä»å ¥åãã©ã¡ãŒã¿ãŒã䜿çšããŠãã€ãã©ã€ã³é¢æ°ãäœæããŸãããã
create or replace function func_division_sales(in_dt1 date, in_dt2 date)
return t_division_sales_report_table
pipelined as
begin
for z in (select t1.division_id,
t1.dt dt1,
t2.dt dt2,
t1.sales_amt sales_amt1,
t2.sales_amt sales_amt2
from (select dt, division_id, sales_amt
from division_sales
where dt = in_dt1) t1,
(select dt, division_id, sales_amt
from division_sales
where dt = in_dt2) t2
where t1.division_id = t2.division_id) loop
pipe row(t_division_sales_report(z.division_id,
z.dt1,
z.dt2,
z.sales_amt1,
z.sales_amt2));
end loop;
end;
ããªãã¯ããããã®ããã«åç §ããããšãã§ããŸãïŒ
select *
from table(func_division_sales(to_date('30.04.2020', 'dd.mm.yyyy'),
to_date('11.09.2020', 'dd.mm.yyyy')));
ãã®ãªã¯ãšã¹ãã§ã¯ããã®æçš¿ã®åé ã«ãããªã¯ãšã¹ããšåãçµæãåŸãããŸãããæ¥ä»ãæ瀺çã«çœ®ãæããããŠããŸãã
ãã€ãã©ã€ã³åãããé¢æ°ã¯ãè€éãªãªã¯ãšã¹ãå ã§ãã©ã¡ãŒã¿ãŒãæž¡ãå¿ èŠãããå Žåã«ã圹ç«ã¡ãŸãã
ããšãã°ãããŒã¿ããã£ã«ã¿ãªã³ã°ããfield1ããã¥ãŒã®å¥¥ã®ã©ããã«é ãããŠããè€éãªãã¥ãŒã«ã€ããŠèããŠã¿ãŸãã
create or replace view complex_view as
select field1, ...
from (select field1, ...
from (select field1, ... from deep_table), table1
where ...),
table2
where ...;
ãŸããfield1ã®å€ãåºå®ãããŠãããã¥ãŒããã®ã¯ãšãªã§ã¯ãå®è¡èšç»ãäžé©åãªå ŽåããããŸãã
select field1, ... from complex_view
where field1 = 'myvalue';
ããããæåã«deep_tableãæ¡ä»¶field1 = 'myvalue'ã§ãã£ã«ã¿ãªã³ã°ãã代ããã«ãã¯ãšãªã¯æåã«ãã¹ãŠã®ããŒãã«ãçµåããäžå¿ èŠã«å€§éã®ããŒã¿ãåŠçããŠãããæ¡ä»¶field1 = 'myvalue'ã§çµæããã£ã«ã¿ãªã³ã°ã§ããŸãããã€ãã©ã€ã³ãã¥ãŒã®ä»£ããã«ãå€ãfield1ã«å²ãåœãŠãããŠãããã©ã¡ãŒã¿ãŒã䜿çšããŠé¢æ°ãäœæãããšããã®è€éããåé¿ã§ããŸãã
ã¯ãšãªã§ã®åççµ±èšã®äœ¿çš
OracleããŒã¿ããŒã¹å ã®åãã¯ãšãªããããŒãã«å ã®ç°ãªãéã®ããŒã¿ãšããã§äœ¿çšããããµãã¯ãšãªãåŠçãããã³ã«åŠçãããããšããããŸããä»åã¯ã©ã®æ¹æ³ã§ããŒãã«ãçµåããã©ã®ã€ã³ããã¯ã¹ãæ¯å䜿çšãããããªããã£ãã€ã¶ã«ã©ã®ããã«å€æãããŸããïŒããšãã°ãæåŸã®ããŒã以éã«å€æŽãããã¢ã«ãŠã³ãæ®é«ã®äžéšãã¢ã«ãŠã³ããã£ã¬ã¯ããªã«æ¥ç¶ããã¯ãšãªã«ã€ããŠèããŠã¿ãŸããå€æŽãããã¢ã«ãŠã³ãæ®é«ã®éšåã¯ããŠã³ããŒãããšã«å€§ããç°ãªããæ°çŸè¡ãå Žåã«ãã£ãŠã¯æ°çŸäžè¡ã«ãªããŸãããã®éšåã®ãµã€ãºã«å¿ããŠã/ * + use_nl * /ã¡ãœããããŸãã¯/ * + use_hash * /ã¡ãœããã®ããããã«ãã£ãŠãå€æŽãããæ®é«ãã¢ã«ãŠã³ããšçµã¿åãããå¿ èŠããããŸããçµåãããããŒãã«ã§ã¯ãªããçµåããããµãã¯ãšãªã§è¡æ°ãããŒãããšã«å€åããå Žåã¯ç¹ã«ãæ¯åçµ±èšãååéããã®ã¯äžäŸ¿ã§ãããã³ã/ * + dynamic_samplingïŒïŒ* /ã¯ããã§å©ãã«ãªããŸãããªã¯ãšã¹ãã®äŸã䜿çšããŠããããã©ã®ããã«åœ±é¿ãããã瀺ããŸããããããŒãã«change_balancesã«ãæ®é«ã®å€æŽãšã¢ã«ãŠã³ãïŒã¢ã«ãŠã³ãã®ãã£ã¬ã¯ããªïŒãå«ãŸããŠãããšããŸãããããã®ããŒãã«ã¯ãåããŒãã«ã§äœ¿çšå¯èœãªaccount_idãã£ãŒã«ãã«ãã£ãŠçµåãããŸããå®éšã®éå§æã«ããããã®ããŒãã«ã«ããã«è¡ãæžã蟌ã¿ããã®å 容ãå€æŽããŸããã
ãŸããchange_balancesããŒãã«ã®æ®å·®ã®å€æŽã®10ïŒ ãååŸããdynamic_samplingã䜿çšããŠãã©ã³ãäœã䜿çšãããã確èªããŸãããã
SQL> EXPLAIN PLAN
2 SET statement_id = 'test1'
3 INTO plan_table
4 FOR with c as
5 (select /*+ dynamic_sampling(change_balances 2)*/
6 account_id, balance_amount
7 from change_balances
8 where mod(account_id, 10) = 0)
9 select a.account_id, a.account_number, c.balance_amount
10 from c, accounts a
11 where c.account_id = a.account_id;
Explained.
SQL>
SQL> SELECT * FROM table (DBMS_XPLAN.DISPLAY);
Plan hash value: 874320301
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9951K| 493M| | 140K (1)| 00:28:10 |
|* 1 | HASH JOIN | | 9951K| 493M| 3240K| 140K (1)| 00:28:10 |
|* 2 | TABLE ACCESS FULL| CHANGE_BALANCES | 100K| 2057K| | 7172 (1)| 00:01:27 |
| 3 | TABLE ACCESS FULL| ACCOUNTS | 10M| 295M| | 113K (1)| 00:22:37 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ACCOUNT_ID"="A"."ACCOUNT_ID")
2 - filter(MOD("ACCOUNT_ID",10)=0)
Note
-----
- dynamic sampling used for this statement (level=2)
20 rows selected.
ãããã£ãŠããã«ã¹ãã£ã³ã䜿çšããŠchange_balancesããŒãã«ãšaccountsããŒãã«ã調ã¹ãããã·ã¥çµåã䜿çšããŠããããçµåããããšãææ¡ãããŠããããšãããããŸãã
ããã§ã¯ãchange_balancesãããµã³ãã«ãå€§å¹ ã«æžãããŸããããæ®ãã®å€æŽã®0.1ïŒ ãåããdynamic_samplingã䜿çšããŠèšç»ãäœã«ãªãããèŠãŠã¿ãŸãããã
SQL> EXPLAIN PLAN
2 SET statement_id = 'test2'
3 INTO plan_table
4 FOR with c as
5 (select /*+ dynamic_sampling(change_balances 2)*/
6 account_id, balance_amount
7 from change_balances
8 where mod(account_id, 1000) = 0)
9 select a.account_id, a.account_number, c.balance_amount
10 from c, accounts a
11 where c.account_id = a.account_id;
Explained.
SQL>
SQL> SELECT * FROM table (DBMS_XPLAN.DISPLAY);
Plan hash value: 2360715730
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 73714 | 3743K| 16452 (1)| 00:03:18 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 73714 | 3743K| 16452 (1)| 00:03:18 |
|* 3 | TABLE ACCESS FULL | CHANGE_BALANCES | 743 | 15603 | 7172 (1)| 00:01:27 |
|* 4 | INDEX RANGE SCAN | IX_ACCOUNTS_ACCOUNT_ID | 104 | | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| ACCOUNTS | 99 | 3069 | 106 (0)| 00:00:02 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(MOD("ACCOUNT_ID",1000)=0)
4 - access("ACCOUNT_ID"="A"."ACCOUNT_ID")
Note
-----
- dynamic sampling used for this statement (level=2)
22 rows selected.
ä»åã¯ãaccountsããŒãã«ããã¹ããããã«ãŒãã§change_balancesããŒãã«ã«ã¢ã¿ãããããã€ã³ããã¯ã¹ã䜿çšããŠã¢ã«ãŠã³ãããè¡ãèªã¿åãããŸãã
dynamic_samplingãã³ããåé€ãããå Žåã2çªç®ã®ã±ãŒã¹ã§ã¯ãèšç»ã¯æåã®ã±ãŒã¹ãšåããŸãŸã§ãããããã¯æé©ã§ã¯ãããŸããã
dynamic_samplingãã³ããšãã®æ°å€åŒæ°ã®å¯èœãªå€ã®è©³çŽ°ã¯ãããã¥ã¡ã³ãã«èšèŒãããŠããŸãã
ããŒã¿ããŒã¹ãªã³ã¯ãä»ããŠããŒã¿ãæ¿å ¥ãããšãã«ã¯ãšãªãã©ã³ãä¿åããæ¹æ³
ç§ãã¡ã¯ãã®åé¡ã解決ããŠããŸããããŒã¿ãœãŒã¹ãµãŒããŒã«ã¯ãçµåããŠããŒã¿ãŠã§ã¢ããŠã¹ã«ããŒãããå¿ èŠã®ããããŒãã«ããããŸããå¿ èŠãªãã¹ãŠã®ETLå€æããžãã¯ãå«ããã¥ãŒããœãŒã¹ãµãŒããŒã«æžã蟌ãŸããŠãããšããŸãããã¥ãŒã¯æé©ã«èšè¿°ãããŠãããããŒãã«ãçµåããæ¹æ³ãšäœ¿çšããã€ã³ããã¯ã¹ãææ¡ãããªããã£ãã€ã¶ãŒã®ãã³ããå«ãŸããŠããŸããããŒã¿ãŠã§ã¢ããŠã¹ã®ãµãŒããŒåŽã§ã¯ãç°¡åãªããšãè¡ãå¿ èŠããããŸãããã¥ãŒããã¿ãŒã²ããããŒãã«ã«ããŒã¿ãæ¿å ¥ããŸãããããŠãããã§åé¡ãçºçããå¯èœæ§ããããŸãã次ã®ãããªã³ãã³ãã§ã¿ãŒã²ããããŒãã«ã«æ¿å ¥ããå Žå
insert into dwh_table
(field1, field2)
select field1, field2 from vw_for_dwh_table@xe_link;
ã®å ŽåãããŒã¿ããŒã¹ãªã³ã¯ãä»ããŠããŒã¿ãèªã¿åããã¥ãŒã«å«ãŸããã¯ãšãªãã©ã³ã®ãã¹ãŠã®ããžãã¯ãç¡èŠã§ããŸãããã®ãã¥ãŒã«çµã¿èŸŒãŸããŠãããã¹ãŠã®ãã³ãã¯ç¡èŠã§ããŸãã
SQL> EXPLAIN PLAN
2 SET statement_id = 'test'
3 INTO plan_table
4 FOR insert into dwh_table
5 (field1, field2)
6 select field1, field2 from vw_for_dwh_table@xe_link;
Explained.
SQL>
SQL> SELECT * FROM table (DBMS_XPLAN.DISPLAY);
Plan hash value: 1788691278
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT|
-------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 2015 | 2 (0)| 00:00:01 | | |
| 1 | LOAD TABLE CONVENTIONAL | DWH_TABLE | | | | | | |
| 2 | REMOTE | VW_FOR_DWH_TABLE | 1 | 2015 | 2 (0)| 00:00:01 | XE_LI~ | R->S |
-------------------------------------------------------------------------------------------------------------
Remote SQL Information (identified by operation id):
----------------------------------------------------
2 - SELECT /*+ OPAQUE_TRANSFORM */ "FIELD1","FIELD2" FROM "VW_FOR_DWH_TABLE" "VW_FOR_DWH_TABLE"
(accessing 'XE_LINK' )
16 rows selected.
ãã¥ãŒã«ã¯ãšãªãã©ã³ãä¿åããã«ã¯ãã«ãŒãœã«ããã¿ãŒã²ããããŒãã«ãžã®ããŒã¿ã®æ¿å ¥ã䜿çšã§ããŸãã
declare
cursor cr is
select field1, field2 from vw_for_dwh_table@xe_link;
cr_row cr%rowtype;
begin
open cr;
loop
fetch cr
into cr_row;
insert into dwh_table
(field1, field2)
values
(cr_row.field1, cr_row.field2);
exit when cr%notfound;
end loop;
close cr;
end;
ã«ãŒãœã«ããã®ã¯ãšãª
select field1, field2 from vw_for_dwh_table@xe_link;
æ¿å ¥ããã®ã§ã¯ãªã
insert into dwh_table
(field1, field2)
select field1, field2 from vw_for_dwh_table@xe_link;
ãœãŒã¹ãµãŒããŒã®ãã¥ãŒã«é 眮ããããªã¯ãšã¹ãã®ãã©ã³ãä¿åããŸãã
䞊åã»ãã·ã§ã³ã§ã®ããã·ãŒãžã£ã®å®è¡
å€ãã®å Žåãã¿ã¹ã¯ã¯ãããã€ãã®èŠªããã·ãŒãžã£ããããã€ãã®äžŠåèšç®ãéå§ãããããããå®äºããã®ãåŸ ã£ãåŸã芪ããã·ãŒãžã£ã®å®è¡ãç¶è¡ããããšã§ããããã¯ããµãŒããŒãªãœãŒã¹ã§èš±å¯ãããŠããå Žåã䞊åã³ã³ãã¥ãŒãã£ã³ã°ã§åœ¹ç«ã¡ãŸãããããè¡ãã«ã¯å€ãã®æ¹æ³ããããŸãã
ãã®ãããªã¡ã«ããºã ã®éåžžã«åçŽãªå®è£ ã«ã€ããŠèª¬æããŸãããã䞊åããã·ãŒãžã£ã¯äžŠåã®ãã¯ã³ã¿ã€ã ããžã§ãã§å®è¡ããã芪ããã·ãŒãžã£ã¯ããããã¹ãŠã®ãžã§ãã®å®äºãã«ãŒãã§åŸ æ©ããŸãã
ãã®ã¡ã«ããºã ã®ã¡ã¿ããŒã¿ã䜿çšããŠããŒãã«ãäœæããŸãããããŸãã䞊åå®è¡ããã·ãŒãžã£ã®ã°ã«ãŒããå«ãããŒãã«ãäœæããŸãããã
create table PARALLEL_PROC_GROUP_LIST
(
group_id INTEGER,
group_name VARCHAR2(4000)
);
comment on column PARALLEL_PROC_GROUP_LIST.group_id
is ' ';
comment on column PARALLEL_PROC_GROUP_LIST.group_name
is ' ';
次ã«ãã°ã«ãŒãã§äžŠè¡ããŠå®è¡ãããã¹ã¯ãªãããå«ãããŒãã«ãäœæããŸãããã®ããŒãã«ã®å ¥åã¯ãéçãŸãã¯åçã«äœæã§ããŸãã
create table PARALLEL_PROC_LIST
(
group_id INTEGER,
proc_script VARCHAR2(4000),
is_active CHAR(1) default 'Y'
);
comment on column PARALLEL_PROC_LIST.group_id
is ' ';
comment on column PARALLEL_PROC_LIST.proc_script
is 'Pl/sql ';
comment on column PARALLEL_PROC_LIST.is_active
is 'Y - active, N - inactive. ';
ãããŠããã°ããŒãã«ãäœæããŸããããã§ãã©ã®ããã·ãŒãžã£ãã©ã®ãžã§ãã§èµ·åããããã®ãã°ãåéããŸãã
create table PARALLEL_PROC_LOG
(
run_id INTEGER,
group_id INTEGER,
proc_script VARCHAR2(4000),
job_id INTEGER,
start_time DATE,
end_time DATE
);
comment on column PARALLEL_PROC_LOG.run_id
is ' run_in_parallel';
comment on column PARALLEL_PROC_LOG.group_id
is ' ';
comment on column PARALLEL_PROC_LOG.proc_script
is 'Pl/sql ';
comment on column PARALLEL_PROC_LOG.job_id
is 'Job_id , ';
comment on column PARALLEL_PROC_LOG.start_time
is ' ';
comment on column PARALLEL_PROC_LOG.end_time
is ' ';
create sequence Seq_Parallel_Proc_Log;
次ã«ã䞊åã¹ããªãŒã ãéå§ããããã®æé ã®ã³ãŒãã瀺ããŸãã
create or replace procedure run_in_parallel(in_group_id integer) as
-- parallel_proc_list.
-- - parallel_proc_list
v_run_id integer;
v_job_id integer;
v_job_id_list varchar2(32767);
v_job_id_list_ext varchar2(32767);
v_running_jobs_count integer;
begin
select seq_parallel_proc_log.nextval into v_run_id from dual;
-- submit jobs with the same parallel_proc_list.in_group_id
-- store seperated with ',' JOB_IDs in v_job_id_list
v_job_id_list := null;
v_job_id_list_ext := null;
for z in (select pt.proc_script
from parallel_proc_list pt
where pt.group_id = in_group_id
and pt.is_active = 'Y') loop
dbms_job.submit(v_job_id, z.proc_script);
insert into parallel_proc_log
(run_id, group_id, proc_script, job_id, start_time, end_time)
values
(v_run_id, in_group_id, z.proc_script, v_job_id, sysdate, null);
v_job_id_list := v_job_id_list || ',' || to_char(v_job_id);
v_job_id_list_ext := v_job_id_list_ext || ' union all select ' ||
to_char(v_job_id) || ' job_id from dual';
end loop;
commit;
v_job_id_list := substr(v_job_id_list, 2);
v_job_id_list_ext := substr(v_job_id_list_ext, 12);
-- loop while not all jobs finished
loop
-- set parallel_proc_log.end_time for finished jobs
execute immediate 'update parallel_proc_log set end_time = sysdate where job_id in (' ||
v_job_id_list_ext ||
' minus select job from user_jobs where job in (' ||
v_job_id_list ||
') minus select job_id from parallel_proc_log where job_id in (' ||
v_job_id_list || ') and end_time is not null)';
commit;
-- check whether all jobs finished
execute immediate 'select count(1) from user_jobs where job in (' ||
v_job_id_list || ')'
into v_running_jobs_count;
-- if all jobs finished then exit
exit when v_running_jobs_count = 0;
-- sleep a little
sys.dbms_lock.sleep(0.1);
end loop;
end;
run_in_parallelããã·ãŒãžã£ãã©ã®ããã«æ©èœãããã確èªããŸãããã䞊åã»ãã·ã§ã³ã§åŒã³åºããã¹ãããã·ãŒãžã£ãäœæããŸãããã
create or replace procedure sleep(in_seconds integer) as
begin
sys.Dbms_Lock.Sleep(in_seconds);
end;
ã°ã«ãŒãã®ååãšã䞊è¡ããŠå®è¡ãããã¹ã¯ãªãããããŒãã«ã«å ¥åããŸãã
insert into PARALLEL_PROC_GROUP_LIST(group_id, group_name) values(1, ' ');
insert into PARALLEL_PROC_LIST(group_id, proc_script, is_active) values(1, 'begin sleep(5); end;', 'Y');
insert into PARALLEL_PROC_LIST(group_id, proc_script, is_active) values(1, 'begin sleep(10); end;', 'Y');
䞊åæé ã®ã°ã«ãŒããéå§ããŸãããã
begin
run_in_parallel(1);
end;
çµäºãããããã°ãèŠãŠã¿ãŸãããã
select * from PARALLEL_PROC_LOG;
RUN_ID | GROUP_ID | PROC_SCRIPT | JOB_ID | å§ãŸãæé | çµäºæé |
1 | 1 | ç¡ç ãéå§ããŸãïŒ5ïŒ; çµãã; | 1 | 2020幎9æ11æ¥15:00:51 | 2020幎9æ11æ¥15:00:56 |
1 | 1 | ç¡ç ãéå§ããŸãïŒ10ïŒ; çµãã; | 2 | 2020幎9æ11æ¥15:00:51 | 09/11/2020 15:01:01 |
ãã¹ãããã·ãŒãžã£ã€ã³ã¹ã¿ã³ã¹ã®å®è¡æéã¯æåŸ ãæºãããŠããããšãããããŸãã
æ®ãç©ãåŒã£åŒµã
ããã©ã³ã¹ããšãããšããããªãå žåçãªéè¡ã®åé¡ã解決ããå€åœ¢ã«ã€ããŠèª¬æããŸããããã¢ã«ãŠã³ãã®æ®é«ã®å€åã®äºå®ã®è¡šããããšããŸããããã«ã¬ã³ããŒã®åæ¥ïŒãã®æ¥ã®æåŸã®æ¥ïŒã®çŸåšã®ã¢ã«ãŠã³ãæ®é«ã瀺ãå¿ èŠããããŸãããã®ãããªæ å ±ã¯ãããŒã¿ãŠã§ã¢ããŠã¹ã§å¿ èŠã«ãªãããšããããããŸããããæ¥ãã«ãŠã³ãã«åãããªãã£ãå Žåã¯ãæåŸã®æ¢ç¥ã®æ®ããç¹°ãè¿ãå¿ èŠããããŸãããµãŒããŒã®ããŒã¿éãšèšç®èœåãèš±ãã°ãPL / SQLã«é ŒãããšãªããSQLã¯ãšãªã䜿çšããŠãã®åé¡ã解決ã§ããŸãã last_valueïŒ* nullãç¡èŠïŒoverïŒpartition by * order by *ïŒé¢æ°ã¯ãããã«åœ¹ç«ã¡ãŸããããã«ãããæåŸã®æ¢ç¥ã®æ®ãããå€æŽããªãã£ãåŸç¶ã®æ¥ä»ã«æ¡åŒµãããŸãã
ããŒãã«ãäœæããŠããã¹ãããŒã¿ãå ¥åããŠã¿ãŸãããã
create table ACCOUNT_BALANCE
(
dt DATE,
account_id INTEGER,
balance_amt NUMBER,
turnover_amt NUMBER
);
comment on column ACCOUNT_BALANCE.dt
is ' ';
comment on column ACCOUNT_BALANCE.account_id
is ' ';
comment on column ACCOUNT_BALANCE.balance_amt
is ' ';
comment on column ACCOUNT_BALANCE.turnover_amt
is ' ';
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('01.01.2020 00:00:00','dd.mm.yyyy hh24.mi.ss'), 1, 23, 23);
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('05.01.2020 01:00:00','dd.mm.yyyy hh24.mi.ss'), 1, 45, 22);
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('05.01.2020 20:00:00','dd.mm.yyyy hh24.mi.ss'), 1, 44, -1);
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('05.01.2020 00:00:00','dd.mm.yyyy hh24.mi.ss'), 2, 67, 67);
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('05.01.2020 20:00:00','dd.mm.yyyy hh24.mi.ss'), 2, 77, 10);
insert into account_balance(dt, account_id, balance_amt, turnover_amt) values(to_date('07.01.2020 00:00:00','dd.mm.yyyy hh24.mi.ss'), 2, 72, -5);
以äžã®ã¯ãšãªã¯åé¡ã解決ããŸãã'cld'ãµãã¯ãšãªã«ã¯æ¥ä»ã®ã«ã¬ã³ããŒãå«ãŸãã 'ab'ãµãã¯ãšãªã§ã¯åæ¥ã®æ®é«ãã°ã«ãŒãåãã 'a'ãµãã¯ãšãªã§ã¯ãã¹ãŠã®ã¢ã«ãŠã³ãã®ãªã¹ããšåã¢ã«ãŠã³ãã®å±¥æŽéå§æ¥ãèšæ¶ããåã¢ã«ãŠã³ãã® 'pre'ãµãã¯ãšãªã§ã¯æåããã®æ¥æ°ã®ã«ã¬ã³ããŒãäœæããŸãç©èªãæåŸã®ãªã¯ãšã¹ãã§ã¯ãåæ¥ã®æåŸã®æ®é«ãåã¢ã«ãŠã³ãã®ã¢ã¯ãã£ããªæ¥ã®ã«ã¬ã³ããŒã«è¿œå ãããå€æŽããªãã£ãæ¥ã«æ¡åŒµãããŸãã
with cld as
(select /*+ materialize*/
to_date('01.01.2020', 'dd.mm.yyyy') + level - 1 dt
from dual
connect by level <= 10),
ab as
(select trunc(dt) dt,
account_id,
max(balance_amt) keep(dense_rank last order by dt) balance_amt,
sum(turnover_amt) turnover_amt
from account_balance
group by trunc(dt), account_id),
a as
(select min(dt) min_dt, account_id from ab group by account_id),
pre as
(select cld.dt, a.account_id from cld left join a on cld.dt >= a.min_dt)
select pre.dt,
pre.account_id,
last_value(ab.balance_amt ignore nulls) over(partition by pre.account_id order by pre.dt) balance_amt,
nvl(ab.turnover_amt, 0) turnover_amt
from pre
left join ab
on pre.dt = ab.dt
and pre.account_id = ab.account_id
order by 2, 1;
ã¯ãšãªã®çµæã¯æåŸ ã©ããã§ãã
DT | ã¢ã«ãŠã³ãID | BALANCE_AMT | TURNOVER_AMT |
01.01.2020 | 1 | 23 | 23 |
02.01.2020 | 1 | 23 | 0 |
2020幎3æ1æ¥ | 1 | 23 | 0 |
2020幎4æ1æ¥ | 1 | 23 | 0 |
2020幎1æ5æ¥ | 1 | 44 | 21 |
06.01.2020 | 1 | 44 | 0 |
07.01.2020 | 1 | 44 | 0 |
2020幎1æ8æ¥ | 1 | 44 | 0 |
2020幎9æ1æ¥ | 1 | 44 | 0 |
10.01.2020 | 1 | 44 | 0 |
2020幎1æ5æ¥ | 2 | 77 | 77 |
06.01.2020 | 2 | 77 | 0 |
07.01.2020 | 2 | 72 | -äº |
2020幎1æ8æ¥ | 2 | 72 | 0 |
2020幎9æ1æ¥ | 2 | 72 | 0 |
10.01.2020 | 2 | 72 | 0 |
è€æ°ã®ã¹ããŒãªãŒã1ã€ã«çµã¿åããã
ããŒã¿ãã¹ãã¬ãŒãžã«ããŒããããšãã«ãããŸããŸãªãœãŒã¹ããååŸãããã®ãšã³ãã£ãã£ã®å±æ§ã®åå¥ã®å±¥æŽãæã€ããšã³ãã£ãã£ã®åäžã®å±¥æŽãäœæããå¿ èŠãããå Žåãåé¡ã¯è§£æ±ºãããããšããããããŸãã 3ã€ã®ç°ãªãããŒãã«ã«ã3ã€ã®ç°ãªãå±æ§ã®å±¥æŽïŒstart_dt-end_dtïŒãããã£ãŠãããã©ââã€ããªããŒprimary_key_idãæã€ãšã³ãã£ãã£ããããšããŸãã
create table HIST1
(
primary_key_id INTEGER,
start_dt DATE,
attribute1 NUMBER
);
insert into HIST1(primary_key_id, start_dt, attribute1) values(1, to_date('2014-01-01','yyyy-mm-dd'), 7);
insert into HIST1(primary_key_id, start_dt, attribute1) values(1, to_date('2015-01-01','yyyy-mm-dd'), 8);
insert into HIST1(primary_key_id, start_dt, attribute1) values(1, to_date('2016-01-01','yyyy-mm-dd'), 9);
insert into HIST1(primary_key_id, start_dt, attribute1) values(2, to_date('2014-01-01','yyyy-mm-dd'), 17);
insert into HIST1(primary_key_id, start_dt, attribute1) values(2, to_date('2015-01-01','yyyy-mm-dd'), 18);
insert into HIST1(primary_key_id, start_dt, attribute1) values(2, to_date('2016-01-01','yyyy-mm-dd'), 19);
create table HIST2
(
primary_key_id INTEGER,
start_dt DATE,
attribute2 NUMBER
);
insert into HIST2(primary_key_id, start_dt, attribute2) values(1, to_date('2015-01-01','yyyy-mm-dd'), 4);
insert into HIST2(primary_key_id, start_dt, attribute2) values(1, to_date('2016-01-01','yyyy-mm-dd'), 5);
insert into HIST2(primary_key_id, start_dt, attribute2) values(1, to_date('2017-01-01','yyyy-mm-dd'), 6);
insert into HIST2(primary_key_id, start_dt, attribute2) values(2, to_date('2015-01-01','yyyy-mm-dd'), 14);
insert into HIST2(primary_key_id, start_dt, attribute2) values(2, to_date('2016-01-01','yyyy-mm-dd'), 15);
insert into HIST2(primary_key_id, start_dt, attribute2) values(2, to_date('2017-01-01','yyyy-mm-dd'), 16);
create table HIST3
(
primary_key_id INTEGER,
start_dt DATE,
attribute3 NUMBER
);
insert into HIST3(primary_key_id, start_dt, attribute3) values(1, to_date('2016-01-01','yyyy-mm-dd'), 10);
insert into HIST3(primary_key_id, start_dt, attribute3) values(1, to_date('2017-01-01','yyyy-mm-dd'), 20);
insert into HIST3(primary_key_id, start_dt, attribute3) values(1, to_date('2018-01-01','yyyy-mm-dd'), 30);
insert into HIST3(primary_key_id, start_dt, attribute3) values(2, to_date('2016-01-01','yyyy-mm-dd'), 110);
insert into HIST3(primary_key_id, start_dt, attribute3) values(2, to_date('2017-01-01','yyyy-mm-dd'), 120);
insert into HIST3(primary_key_id, start_dt, attribute3) values(2, to_date('2018-01-01','yyyy-mm-dd'), 130);
ç®æšã¯ã3ã€ã®å±æ§ã®åäžã®å€æŽå±¥æŽã1ã€ã®ããŒãã«ã«ããŒãããããšã§ãã
以äžã¯ããã®åé¡ã解決ããã¯ãšãªã§ããæåã«ãããŸããŸãªå±æ§ã®ããŸããŸãªãœãŒã¹ããã®ããŒã¿ã䜿çšããŠå¯Ÿè§ããŒãã«q1ã圢æããŸãïŒãœãŒã¹ã«ååšããªãå±æ§ã¯nullã§åããããŸãïŒã次ã«ãlast_valueïŒ* nullãç¡èŠïŒé¢æ°ã䜿çšããŠã察è§ããŒãã«ãåäžã®å±¥æŽã«æããããŸããæåŸã®æ¢ç¥ã®å±æ§å€ããå€æŽããªãã£ãæ¥ä»ãŸã§æ¡åŒµãããŸãïŒ
select primary_key_id,
start_dt,
nvl(lead(start_dt - 1)
over(partition by primary_key_id order by start_dt),
to_date('9999-12-31', 'yyyy-mm-dd')) as end_dt,
last_value(attribute1 ignore nulls) over(partition by primary_key_id order by start_dt) as attribute1,
last_value(attribute2 ignore nulls) over(partition by primary_key_id order by start_dt) as attribute2,
last_value(attribute3 ignore nulls) over(partition by primary_key_id order by start_dt) as attribute3
from (select primary_key_id,
start_dt,
max(attribute1) as attribute1,
max(attribute2) as attribute2,
max(attribute3) as attribute3
from (select primary_key_id,
start_dt,
attribute1,
cast(null as number) attribute2,
cast(null as number) attribute3
from hist1
union all
select primary_key_id,
start_dt,
cast(null as number) attribute1,
attribute2,
cast(null as number) attribute3
from hist2
union all
select primary_key_id,
start_dt,
cast(null as number) attribute1,
cast(null as number) attribute2,
attribute3
from hist3) q1
group by primary_key_id, start_dt) q2
order by primary_key_id, start_dt;
çµæã¯æ¬¡ã®ããã«ãªããŸãã
PRIMARY_KEY_ID | START_DT | END_DT | ATTRIBUTE1 | ATTRIBUTE2 | ATTRIBUTE3 |
1 | 2014幎1æ1æ¥ | 2014幎12æ31æ¥ | 7 | ãã« | ãã« |
1 | 2015幎1æ1æ¥ | 2015幎12æ31æ¥ | 8 | 4 | ãã« |
1 | 2016幎1æ1æ¥ | 2016幎12æ31æ¥ | ãã€ã³ | äº | å |
1 | 2017幎1æ1æ¥ | 2017幎12æ31æ¥ | ãã€ã³ | 6 | 20 |
1 | 2018幎1æ1æ¥ | 31.12.9999 | ãã€ã³ | 6 | 30 |
2 | 2014幎1æ1æ¥ | 2014幎12æ31æ¥ | 17 | ãã« | ãã« |
2 | 2015幎1æ1æ¥ | 2015幎12æ31æ¥ | 18 | 14 | ãã« |
2 | 2016幎1æ1æ¥ | 2016幎12æ31æ¥ | 19 | 15 | 110 |
2 | 2017幎1æ1æ¥ | 2017幎12æ31æ¥ | 19 | 16 | 120 |
2 | 2018幎1æ1æ¥ | 31.12.9999 | 19 | 16 | 130 |
ããŒãã©ã€ã¶ãŒ
åºåããã£ãŒã«ãã®åœ¢åŒã§éä¿¡ãããããŒã¿ãæ£èŠåãããšãåé¡ãçºçããããšããããŸããããšãã°ã次ã®ãããªããŒãã«ã®åœ¢åŒã§ïŒ
create table DENORMALIZED_TABLE
(
id INTEGER,
val VARCHAR2(4000)
);
insert into DENORMALIZED_TABLE(id, val) values(1, 'aaa,cccc,bb');
insert into DENORMALIZED_TABLE(id, val) values(2, 'ddd');
insert into DENORMALIZED_TABLE(id, val) values(3, 'fffff,e');
ãã®ã¯ãšãªã¯ãã³ã³ãã«ãªã³ã¯ããããã£ãŒã«ããè€æ°ã®è¡ãšããŠè²Œãä»ããããšã«ãããããŒã¿ãæ£èŠåããŸãã
select id, regexp_substr(val, '[^,]+', 1, column_value) val, column_value
from denormalized_table,
table(cast(multiset
(select level
from dual
connect by regexp_instr(val, '[^,]+', 1, level) > 0) as
sys.odcinumberlist))
order by id, column_value;
çµæã¯æ¬¡ã®ããã«ãªããŸãã
ID | VAL | COLUMN_VALUE |
1 | aaa | 1 |
1 | cccc | 2 |
1 | bb | 3 |
2 | ddd | 1 |
3 | fffff | 1 |
3 | e | 2 |
SVG圢åŒã§ã®ã¬ã³ããªã³ã°
å€ãã®å ŽåãããŒã¿ããŒã¹ã«ä¿åãããŠããæ°å€ææšãäœããã®åœ¢ã§èŠèŠåããããšããèŠæããããŸããããšãã°ãã°ã©ãããã¹ãã°ã©ã ããã£ãŒããäœæããŸããOracleBIãªã©ã®å°çšããŒã«ã圹ç«ã¡ãŸãããã ãããããã®ããŒã«ã®ã©ã€ã»ã³ã¹ã«ã¯ã³ã¹ãããããå¯èœæ§ãããããããã®ã»ããã¢ããã«ã¯ãå®æããç»åãè¿ãOracleãžã®ããªã³ã¶ããŒãSQLã¯ãšãªã®èšè¿°ãããæéããããå¯èœæ§ããããŸããã¯ãšãªã䜿çšããŠããã®ãããªç»åãSVG圢åŒã§ãã°ããæç»ããæ¹æ³ãäŸãæããŠèª¬æããŸãããã
ããŒã¿ãå«ãããŒãã«ããããšããŸã
create table graph_data(dt date, val number, radius number);
insert into graph_data(dt, val, radius) values (to_date('01.01.2020','dd.mm.yyyy'), 12, 3);
insert into graph_data(dt, val, radius) values (to_date('02.01.2020','dd.mm.yyyy'), 15, 4);
insert into graph_data(dt, val, radius) values (to_date('05.01.2020','dd.mm.yyyy'), 17, 5);
insert into graph_data(dt, val, radius) values (to_date('06.01.2020','dd.mm.yyyy'), 13, 6);
insert into graph_data(dt, val, radius) values (to_date('08.01.2020','dd.mm.yyyy'), 3, 7);
insert into graph_data(dt, val, radius) values (to_date('10.01.2020','dd.mm.yyyy'), 20, 8);
insert into graph_data(dt, val, radius) values (to_date('11.01.2020','dd.mm.yyyy'), 18, 9);
dtã¯é¢é£æ§ã®ããæ¥ä»ã
valã¯æ°å€ã€ã³ãžã±ãŒã¿ãŒã§ããããã®ãã€ããã¯ã¹ã¯æéã®çµéãšãšãã«èŠèŠåãã
ãŸããradiusã¯ããã®ãããªååŸã®åã®åœ¢ã§æç»ãããã1ã€ã®æ°å€ã€ã³ãžã±ãŒã¿ãŒã§ãã
SVGãã©ãŒãããã«ã€ããŠå°ã話ããŸããããããã¯ãææ°ã®ãã©ãŠã¶ãŒã§è¡šç€ºããããä»ã®ã°ã©ãã£ãã¯åœ¢åŒã«å€æãããã§ãããã¯ãã«ã°ã©ãã£ãã¯åœ¢åŒã§ãããã®äžã§ããšããããããªãã¯ç·ãåãæããããã¹ããæžãããšãã§ããŸãïŒ
<line x1="94" x2="94" y1="15" y2="675" style="stroke:rgb(150,255,255); stroke-width:1px"/>
<circle cx="30" cy="279" r="3" style="fill:rgb(255,0,0)"/>
<text x="7" y="688" font-size="10" fill="rgb(0,150,255)">2020-01-01</text>
以äžã¯ããã®ããŒãã«ã®ããŒã¿ããã°ã©ããããããããOracleãžã®SQLã¯ãšãªã§ããããã§ãconstãµãã¯ãšãªã«ã¯ãç»åãµã€ãºããã£ãŒã軞äžã®ã©ãã«ã®æ°ãç·ãšåã®è²ããã©ã³ããµã€ãºãªã©ãããŸããŸãªå®æ°èšå®ãå«ãŸããŠããŸãã gd1ãµãã¯ãšãªã§ã¯ãgraph_dataããŒãã«ã®ããŒã¿ãå³ã®x座æšãšy座æšã«å€æããŸãã gd2ãµãã¯ãšãªã¯ãåã®æç¹ãèšæ¶ããŠãããããããæ°ãããã€ã³ãã«ç·ãåŒãå¿ èŠããããŸãã 'header'ãããã¯ã¯ãèæ¯ãçœãç»åã®ããããŒã§ãã 'verticallines'ãããã¯ã¯åçŽç·ãæç»ããŸãã 'åçŽç·ã®äžã®æ¥ä»'ãããã¯ã¯ãx軞ã®æ¥ä»ã«ã©ãã«ãä»ããŸãã 'horizoâântallines'ãããã¯ã¯æ°Žå¹³ç·ãæç»ããŸãã ãæ°Žå¹³ç·ã®è¿ãã®å€ããããã¯ã¯ãy軞äžã®å€ã«ã©ãã«ãä»ããŸãã 'circles'ãããã¯ã¯ãgraph_dataããŒãã«ã«æå®ãããååŸã®åãæç»ããŸãã'graph data'ãããã¯ã¯ãè¡ã®graph_dataããŒãã«ããvalã€ã³ãžã±ãŒã¿ãŒã®ãã€ããã¯ã¹ã®ã°ã©ããäœæããŸãã 'footer'ãããã¯ã¯ãæ«å°Ÿã®ã¿ã°ãè¿œå ããŸãã
with const as
(select 700 viewbox_width,
700 viewbox_height,
30 left_margin,
30 right_margin,
15 top_margin,
25 bottom_margin,
max(dt) - min(dt) + 1 num_vertical_lines,
11 num_horizontal_lines,
'rgb(150,255,255)' stroke_vertical_lines,
'1px' stroke_width_vertical_lines,
10 font_size_dates,
'rgb(0,150,255)' fill_dates,
23 x_dates_pad,
13 y_dates_pad,
'rgb(150,255,255)' stroke_horizontal_lines,
'1px' stroke_width_horizontal_lines,
10 font_size_values,
'rgb(0,150,255)' fill_values,
4 x_values_pad,
2 y_values_pad,
'rgb(255,0,0)' fill_circles,
'rgb(51,102,0)' stroke_graph,
'1px' stroke_width_graph,
min(dt) min_dt,
max(dt) max_dt,
max(val) max_val
from graph_data),
gd1 as
(select graph_data.dt,
const.left_margin +
(const.viewbox_width - const.left_margin - const.right_margin) *
(graph_data.dt - const.min_dt) / (const.max_dt - const.min_dt) x,
const.viewbox_height - const.bottom_margin -
(const.viewbox_height - const.top_margin - const.bottom_margin) *
graph_data.val / const.max_val y,
graph_data.radius
from graph_data, const),
gd2 as
(select dt,
round(nvl(lag(x) over(order by dt), x)) prev_x,
round(x) x,
round(nvl(lag(y) over(order by dt), y)) prev_y,
round(y) y,
radius
from gd1)
/* header */
select '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' txt
from dual
union all
select '<svg version="1.1" width="' || viewbox_width || '" height="' ||
viewbox_height || '" viewBox="0 0 ' || viewbox_width || ' ' ||
viewbox_height ||
'" style="background:yellow" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">'
from const
union all
select '<title>Test graph</title>'
from dual
union all
select '<desc>Test graph</desc>'
from dual
union all
select '<rect width="' || viewbox_width || '" height="' || viewbox_height ||
'" style="fill:white" />'
from const
union all
/* vertical lines */
select '<line x1="' ||
to_char(round(left_margin +
(viewbox_width - left_margin - right_margin) *
(level - 1) / (num_vertical_lines - 1))) || '" x2="' ||
to_char(round(left_margin +
(viewbox_width - left_margin - right_margin) *
(level - 1) / (num_vertical_lines - 1))) || '" y1="' ||
to_char(round(top_margin)) || '" y2="' ||
to_char(round(viewbox_height - bottom_margin)) || '" style="stroke:' ||
const.stroke_vertical_lines || '; stroke-width:' ||
const.stroke_width_vertical_lines || '"/>'
from const
connect by level <= num_vertical_lines
union all
/* dates under vertical lines */
select '<text x="' ||
to_char(round(left_margin +
(viewbox_width - left_margin - right_margin) *
(level - 1) / (num_vertical_lines - 1) - x_dates_pad)) ||
'" y="' ||
to_char(round(viewbox_height - bottom_margin + y_dates_pad)) ||
'" font-size="' || font_size_dates || '" fill="' || fill_dates || '">' ||
to_char(min_dt + level - 1, 'yyyy-mm-dd') || '</text>'
from const
connect by level <= num_vertical_lines
union all
/* horizontal lines */
select '<line x1="' || to_char(round(left_margin)) || '" x2="' ||
to_char(round(viewbox_width - right_margin)) || '" y1="' ||
to_char(round(top_margin +
(viewbox_height - top_margin - bottom_margin) *
(level - 1) / (num_horizontal_lines - 1))) || '" y2="' ||
to_char(round(top_margin +
(viewbox_height - top_margin - bottom_margin) *
(level - 1) / (num_horizontal_lines - 1))) ||
'" style="stroke:' || const.stroke_horizontal_lines ||
'; stroke-width:' || const.stroke_width_horizontal_lines || '"/>'
from const
connect by level <= num_horizontal_lines
union all
/* values near horizontal lines */
select '<text text-anchor="end" x="' ||
to_char(round(left_margin - x_values_pad)) || '" y="' ||
to_char(round(viewbox_height - bottom_margin -
(viewbox_height - top_margin - bottom_margin) *
(level - 1) / (num_horizontal_lines - 1) +
y_values_pad)) || '" font-size="' || font_size_values ||
'" fill="' || fill_values || '">' ||
to_char(round(max_val / (num_horizontal_lines - 1) * (level - 1), 2)) ||
'</text>'
from const
connect by level <= num_horizontal_lines
union all
/* circles */
select '<circle cx="' || to_char(gd2.x) || '" cy="' || to_char(gd2.y) ||
'" r="' || gd2.radius || '" style="fill:' || const.fill_circles ||
'"/>'
from gd2, const
union all
/* graph data */
select '<line x1="' || to_char(gd2.prev_x) || '" x2="' || to_char(gd2.x) ||
'" y1="' || to_char(gd2.prev_y) || '" y2="' || to_char(gd2.y) ||
'" style="stroke:' || const.stroke_graph || '; stroke-width:' ||
const.stroke_width_graph || '"/>'
from gd2, const
union all
/* footer */
select '</svg>' from dual;
ã¯ãšãªçµæã¯ãæ¡åŒµåã* .svgã®ãã¡ã€ã«ã«ä¿åããŠããã©ãŠã¶ã§è¡šç€ºã§ããŸããå¿ èŠã«å¿ããŠãä»»æã®ãŠãŒãã£ãªãã£ã䜿çšããŠãä»ã®ã°ã©ãã£ãã¯åœ¢åŒã«å€æããããã¢ããªã±ãŒã·ã§ã³ã®WebããŒãžã«é 眮ãããã§ããŸãã
çµæã¯æ¬¡ã®å³ã§ãã
Oracleã¡ã¿ããŒã¿æ€çŽ¢ã¢ããªã±ãŒã·ã§ã³
è€æ°ã®ãµãŒããŒã®æ å ±ãäžåºŠã«æ€çŽ¢ããŠãOracleã®ãœãŒã¹ã³ãŒãã§äœããèŠã€ããããšããŠãããšæ³åããŠã¿ãŠãã ãããããã¯ãOracleããŒã¿ãã£ã¯ã·ã§ããªãªããžã§ã¯ãã®æ€çŽ¢ã«é¢ãããã®ã§ããæ€çŽ¢ã®äœæ¥å Žæã¯ããŠãŒã¶ãŒããã°ã©ããŒãæ€çŽ¢æååãå ¥åãããã®æ€çŽ¢ãå®è¡ããOracleãµãŒããŒã®ãã§ãã¯ããã¯ã¹ãéžæããWebã€ã³ã¿ãŒãã§ã€ã¹ã§ãã
Webæ€çŽ¢ãšã³ãžã³ã¯ãéè¡ã®è€æ°ã®ç°ãªãããŒã¿ããŒã¹ã§OracleãµãŒããŒãªããžã§ã¯ãã®è¡ãåæã«æ€çŽ¢ã§ããŸããããšãã°ã次ãæ€çŽ¢ã§ããŸãã
- Oracle 61209, ?
- accounts ( .. database link)?
- , , ORA-20001 â â?
- IX_CLIENTID - SQL-?
- - ( .. database link) , , , ..?
- - - ? .
- Oracle ? , wm_concat Oracle. .
- - , , ? , Oracle sys_connect_by_path, regexp_instr push_subq.
æ€çŽ¢çµæã«åºã¥ããŠããŠãŒã¶ãŒã«ã¯ãã©ã®é¢æ°ãããã·ãŒãžã£ãããã±ãŒãžãããªã¬ãŒããã¥ãŒãªã©ã®ã³ãŒãå ã®ã©ã®ãµãŒããŒã«é¢ããæ å ±ãæäŸãããŸããå¿ èŠãªçµæãèŠã€ãããŸããã
ãã®ãããªæ€çŽ¢ãšã³ãžã³ãã©ã®ããã«å®è£ ãããŠãããã説æããŸãããã
ã¯ã©ã€ã¢ã³ãåŽã¯è€éã§ã¯ãããŸããã Webã€ã³ã¿ãŒãã§ã€ã¹ã¯ããŠãŒã¶ãŒãå ¥åããæ€çŽ¢æååãæ€çŽ¢ãããµãŒããŒã®ãªã¹ããããã³ãŠãŒã¶ãŒã®ãã°ã€ã³ãåãåããŸãã WebããŒãžã¯ããããããã³ãã©ãŒãµãŒããŒäžã®Oracleã¹ãã¢ãããã·ãŒãžã£ã«æž¡ããŸããæ€çŽ¢ãšã³ãžã³ãžã®ãªã¯ãšã¹ãã®å±¥æŽãã€ãŸã念ã®ããã誰ãã©ã®ãªã¯ãšã¹ããå®è¡ãããããã°ã«èšé²ãããŸãã
æ€çŽ¢ã¯ãšãªãåä¿¡ããåŸãOracleæ€çŽ¢ãµãŒããŒã®ãµãŒããŒåŽã¯ãéžæããOracleãµãŒããŒäžã®ããŒã¿ããŒã¹ãªã³ã¯äžã®æ¬¡ã®ããŒã¿ãã£ã¯ã·ã§ããªãã¥ãŒãã¹ãã£ã³ããŠãç®çã®æååãæ€çŽ¢ãã䞊åãžã§ãã§ããã€ãã®ããã·ãŒãžã£ãå®è¡ããŸãïŒdba_col_commentsãdba_jobsãdba_mviewsãdba_objectsãdba_scheduler_jobsãdba_ba_sourceãdba_scheduler_job ãdba_viewsãåããã·ãŒãžã£ã¯ãäœããèŠã€ãã£ãå Žåãæ€çŽ¢çµæããŒãã«ã«ïŒå¯Ÿå¿ããæ€çŽ¢ã¯ãšãªIDã䜿çšããŠïŒèŠã€ãã£ããã®ãæžã蟌ã¿ãŸãã
ãã¹ãŠã®æ€çŽ¢æé ãå®äºãããšãã¯ã©ã€ã¢ã³ãããŒãã¯ã察å¿ããæ€çŽ¢ã¯ãšãªIDã䜿çšããŠæ€çŽ¢çµæããŒãã«ã«æžã蟌ãŸãããã¹ãŠã®ãã®ããŠãŒã¶ãŒã«æäŸããŸãã
ããããããã ãã§ã¯ãããŸããã OracleããŒã¿èŸæžã®æ€çŽ¢ã«å ããŠãInformaticaPowerCenterãªããžããªã§ã®æ€çŽ¢ã説æãããŠããã¡ã«ããºã ã«çµã¿èŸŒãŸããŸããã Informatica PowerCenterã¯ãSberbankãããŸããŸãªæ å ±ãããŒã¿ãŠã§ã¢ããŠã¹ã«ããŒãããããã«äœ¿çšãã人æ°ã®ããETLããŒã«ã§ãã Informatica PowerCenterã«ã¯ããªãŒãã³ã§ååã«ææžåããããªããžããªæ§é ããããŸãããã®ãªããžããªã§ã¯ãOracleããŒã¿ãã£ã¯ã·ã§ããªãšåãæ¹æ³ã§æ å ±ãæ€çŽ¢ã§ããŸãã Informatica PowerCenterã§éçºãããããŠã³ããŒãã³ãŒãã§äœ¿çšãããŠããããŒãã«ãšãã£ãŒã«ãã¯äœã§ããïŒããŒãå€æãšæ瀺çãªSQLã¯ãšãªã«ã¯äœããããŸããïŒãã®ãã¹ãŠã®æ å ±ã¯ããªããžããªã®æ§é ã§å©çšå¯èœã§ãããèŠã€ããããšãã§ããŸãã PowerCenterã®æ奜家ã®ããã«ãç§ãã¡ã®æ€çŽ¢ãšã³ãžã³ããããã³ã°ãã»ãã·ã§ã³ããŸãã¯ã¯ãŒã¯ãããŒãæ€çŽ¢ããããã«æ¬¡ã®ãªããžããªã®å Žæãã¹ãã£ã³ããããšãæžããŸããæ€çŽ¢æååãã©ããã«å«ãïŒsqlãªãŒããŒã©ã€ããããã¬ããå±æ§ãããŒãããããã³ã°ã®ãœãŒã¹å®çŸ©ããœãŒã¹å®çŸ©ããããã³ã°ã®ã¿ãŒã²ããå®çŸ©ãtarget_definitionsããããã³ã°ãããã¬ãããã¯ãŒã¯ãããŒãã¯ãŒã¯ã¬ãããã»ãã·ã§ã³ãã³ãã³ããåŒããŒããã»ãã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ããœãŒã¹å®çŸ©ãã£ãŒã«ããã¿ãŒã²ããå®çŸ©ãã£ãŒã«ããé»åã¡ãŒã«ã¿ã¹ã¯ã
: , SberProfi DWH/BigData.
SberProfi DWH/BigData , Hadoop, Teradata, Oracle DB, GreenPlum, BI Qlik, SAP BO, Tableau .