APEX-poznámky

APEX-poznámky

[TOC]

Poznámky APEX.


Odkazy – reference – definice

Oracle TEXT

Oracle TEXT

Workspace vs. Schema vs. User

Schema je klasické databázové schema (prostor v dané databázi přidělený definovaným uživatelům).
Workspace je něco podobného ale co se vztahuje k aplikacím a uživatelům v rámci APEXu. Workspace může využívat libovolné (např. s jinými Workspace společné) databázové schema.
Další vysvětlení in English: zde

APEX -nastavení

ADMIN

ADMIN/P1

Databásové linky – PRIVILEGES

Pokud chci dělat databasové linky atd (např. uživatel petr) potřebuji příslušná privilegia (v tomto případě CREATE DATABASE LINK).
Nejjednoduší je přidat si všechna:
GRANT ALL to petr
SQLPLUS:

SQL>conn sys as sysdba
SQL>grant all to petr
2   /
SQL>

Nastavení print serveru

enter image description here

Inicializace e-mail package pro APEX

SQL> @$ORACLE_HOME/javavm/install/initjvm.sql
SQL> @$ORACLE_HOME/rdbms/admin/initplsj.sql

Je ale pravda, že jsem nic takového v mé instalaci nenašel !!

Nastavení vzdáleného přístupu (když funguje jen lokální přístup)

EXEC dbms_xdb.setListenerLocalAccess(l_access => FALSE);

(Podrobněji na Evernote)

EMAIL – nastavení a API

https://docs.oracle.com/database/121/AEAPI/apex_mail.htm#AEAPI341

APEX-návody jak na to

JOBS

ZDE

BLOB – soubory

Toto je zápis pro Quick SQL:

uk_soubory /insert 2
      soubor blob
      mimetype vc255
      nazev vc255
      last_update date
      charset vc128

Autologin / Remember me – automatické znovu-přihlášení

Oracle & APEX Geekery
apex-at-work

Hierarchická struktura – strom

jen pomocí CSS

Super ! Jenom je zapotřebí přidat do CSS – .tree ul {margin:0px}
Tedy celé CSS bude takto:

.tree {
  overflow-x: auto;
}
.tree ul {
  padding-top: 20px;
  position: relative;
  white-space: nowrap;
  margin: 0px;
}
.tree li {
  display: inline-block;
  white-space: nowrap;
  vertical-align: top;
  margin: 0 -2px;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 5px 0;
  transition: all .5s;
  -webkit-transition: all .5s;
  -moz-transition: all .5s;
}
/*We will use ::before and ::after to draw the connectors*/
.tree li::before,.tree li::after {
  content: '';
  position: absolute;
  top: 0;
  right: 50%;
  border-top: 1px solid #ccc;
  width: 50%;
  height: 20px;
}
.tree li::after {
  right: auto;
  left: 50%;
  border-left: 1px solid #ccc;
}
/*We need to remove left-right connectors from elements without any siblings*/
.tree li:only-child::after,.tree li:only-child::before {
  display: none;
}
/*Remove space from the top of single children*/
.tree li:only-child {
  padding-top: 0;
}
/*Remove left connector from first child and 
right connector from last child*/
.tree li:first-child::before,.tree li:last-child::after {
  border: 0 none;
}
/*Adding back the vertical connector to the last nodes*/
.tree li:last-child::before {
  border-right: 1px solid #ccc;
  border-radius: 0 5px 0 0;
}
.tree li:first-child::after {
  border-radius: 5px 0 0 0;
}
/*Time to add downward connectors from parents*/
.tree ul ul::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  border-left: 1px solid #ccc;
  width: 0;
  height: 20px;
}
.tree li a {
  border: 1px solid #ccc;
  padding: 5px 10px;
  text-decoration: none;
  color: #666;
  font-family: arial, verdana, tahoma;
  font-size: 11px;
  display: inline-block;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}
/*Time for some hover effects*/
/*We will apply the hover effect the the lineage of the element also*/
.tree li a:hover,.tree li a:hover+ul li a {
  background: #c8e4f8;
  color: #000;
  border: 1px solid #94a0b4;
}
/*Connector styles on hover*/
.tree li a:hover+ul li::after,.tree li a:hover+ul li::before,.tree li a:hover+ul::before {
  border-color: #94a0b4;
}

Klasický strom (APEX 5.0 ->)

Select musí být v tomto formátu (důležité je pořadí nikoli názvy polí)

SELECT status, level, name, icon, id, tooltip, link 
FROM ... 
WHERE ... 
START WITH... 
CONNECT BY PRIOR id = pid 

ORDER SIBLINGS BY ...

Takže např.:

SELECT case WHEN connect_by_isleaf = 1 THEN 0 WHEN level = 1 THEN 1 ELSE -1 END as status,
       level,
       ename as title,
       'icon-tree-folder' as icon,
       empno as value,
       ename as tooltip,
       NULL as link
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
ORDER SIBLINGS BY ename

nebo sofistikovanější s využitím WITH a vrcholem “Všechny projekty”:

with data as (  
select 'M' as link_type,  
null as parent,  
'Všechny projekty' as id,  
'Všechny projekty' as name,  
null as sub_id  
from dokumenty  
union  
select distinct('C') as link_type,  
'Všechny projekty' as parent,  
projekt as id,  
projekt as name,  
null as sub_id  
from dokumenty  
union  
select 'P' as link_type,  
projekt as parent,  
nazev as id,  
nazev as name,  
null as sub_id  
from dokumenty  
)

select case when connect_by_isleaf = 1 then 0  
when level = 1 then 1  
else -1  
end as status,  
level,  
name as title,  
null as icon,  
id as value,  
'View' as tooltip,  
null as link  
from data

start with parent is null  
connect by prior id = parent  
order siblings by name

Read Only stránka – podmíněně

V definici stránky je přímo možno zapsat podmínku, kdy je stránka s formulářem jen Read Only.

APEX -finty

Nastavení filtrů při volání interaktivního reportu

Do linku na příslušný IR je zapotřebí dopsat také – Clear Cache: RIR,CIR
If you want to apply a filter on an interactive report when linking from another page you can use the following operators.

Function Meaning
IREQ_<COLUMN_NAME> Equals
IR_<COLUMN_NAME > Same as IREQ
LT_<COLUMN_NAME > Less than
IRLTE_<COLUMN_NAME > Less than or equal to
IRGT_<COLUMN_NAME > Greater then
IRGTE_<COLUMN_NAME > Greater then or equal to
IRLIKE_<COLUMN_NAME > Like operator
IRN_<COLUMN_NAME > Is Null
IRNN_<COLUMN_NAME > Is not Null
IRC_<COLUMN_NAME > Contains
IRNC_<COLUMN_NAME > Not Contains
You can also use above functions in a saved report, then you have to use IR_REPORT_.

Sometimes the page with the interactive report can be accessed by multiple pages and you would like to reset the filters already applied to the interactive report.

Tlačítko RESET INTERAKTIV REPORT

  • volá dynamickou akci s tímto PLSQL a refreshem:
declare
    l_region_id apex_application_page_regions.region_id%type;
begin

    select region_id into l_region_id
    from apex_application_page_regions
    where application_id = :APP_ID
    and page_id = :APP_PAGE_ID
    and static_id = 'region-static-id';--V IR regionu vyplnit STATIC ID a sem odpovídající doplnit
    
    apex_ir.reset_report(
        p_page_id => :APP_PAGE_ID
      , p_region_id => l_region_id
      , p_report_id => NULL
    );
    
end;

Pak stačí spustit dynamickou akci s tímto PL/SQL a přidat ještě k němu jednu akci s refresh.
!! POZOR !! nefunguje, když se použije volání uložených reportů Public/Privat přes http link např. při technice s CARDs reportem pro zobrazení těchto reportů. Pokud se uložené reporty volí přes select list v liště reportu, tak to funguje dobře.
Pak ale asi jde použít druhá metoda (zatím jsem nezkoušel):

APEX_IR.RESET_REPORT(
    p_page_id      IN NUMBER,
    p_region_id    IN NUMBER,
    p_report_alias IN VARCHAR2 DEFAULT NULL);

kde se použije alias uloženého reportu.
Ref.:
Super!! – na konci článku varianta pro APEX 5

Report s checkbox sloupcem

Report with Checkboxes (an update)

!! Obnovení smazané aplikace !!

http://apexplained.wordpress.com/2012/07/12/recover-a-deleted-apex-page-or-application/

User account “Locked” nebo “Expired”

Korektní vstup do SQLPLUS (Příkazový řádek):

  • Příkazový řádek (Windows)
  • CD D:/apex
  • spustit SQLPLUS /NOCONNET
  • a pak přihlášení např CONNECT SYS AS SYSDBA

Pokud je EXPIRED stačí se v SQLPLUS přihlásit se starým heslem:
CONNECT petr
zadat staré heslo a nabídne se hned možnost zapsat nové.

Pokud je LOCKED tak následující:
Most of the example user accounts are locked when you install the database.
You need to logon as sys or system and unlock the accounts you want to use

ALTER USER petr ACCOUNT UNLOCK;

This will give you the list of accounts that are locked

SELECT USERNAME FROM DBA_USERS
WHERE ACCOUNT_STATUS LIKE '%LOCKED%'
ORDER BY USERNAME

And accounts could also be expired

SELECT DISTINCT ACCOUNT_STATUS FROM DBA_USERS

ACCOUNT_STATUS:

LOCKED
OPEN
EXPIRED
EXPIRED & LOCKED

Jak na to

Export reportu

ZDE (nevyzkoušeno)
ZDE plugin (nevyzkoušeno)
ZDE asi nejlíp

LDAP

Jak nastavit …

Odstranění přebytečných mezer ze záznamů (RegExp)

update tabulka set sloupec = REGEXP_REPLACE( sloupec, '[[:space:]]{2,}', ' ' )

vyruší vícenásobné mezery (nahradí jednou mezerou) ve sloupci sloupec tabulky tabulka.
Zrušení koncových mezer:

update tabulka set sloupec = RTRIM(sloupec)

(zkoušel jsem a nějak to nešlo – nakonec nejjeduší bylo vytvořit dialogovou modal stránku volanou linkem s naplněním item položky)

javascript:$.event.trigger('DAEvent','#EMPNO#');

Ref.: návod

Icony v APEX 5

<span class="t-Icon fa fa-anchor" aria-hidden="true"></span>

Zmenšení pole icony v prvním sloupci tabulky

.minimize-first-table-col td:first-child{
  width: 1%;
  overflow: visible;
  font-size:120%;
  padding: 8px;
}

A přidat class do interaktivního reportu:
minimize-first-table-col

Napovídací bubliny u položek tabulky

HTML Expression:

<span title1="#text bubliny- pole tabulky#">#pole tabulky#</span>

CSS (vloženo do definice stránky):

/*Napovídací bubliny - u příslušných položek musí být přidán vlastní atribut TITLE1 = "....text...." */
span[title1] {
position: relative; 
border-bottom: 1px solid #1081DD; 
cursor:default
}
span[title1]:hover:after {
border: 1px solid #0D6AB7; 
color: #fff; 
border-radius: .2em; 
background: #1081DD; 
content: attr(title1); 
position: absolute; 
top: -1em; 
left: 10; 
padding: 0 .2em; 
width: 8em
}

Multiple SELECT as string

Zajímavá funkce, která udělá z vyselektovaných položek string, např.:
select listagg(SEARCH_KEY,', ') within group (order by SEARCH_KEY)from PREHLED
vytvoří řetězec všech nalezených SEARCH_KEY oddělených čárkou z PREHLED.
V případě, že chci každou položku na novém řádku je zapotřebí použit něco jako:
listagg(search_key,CHR(13)||CHR(10)) within group (order by search_key) searchkey_List
Ref.:
TechOnThe Net
Stack Overflow
unikátní výskyt

APEXové URL – parametry

Gelis Blog

URL volání aplikace a přihlášení

Je toto možnost, jak nastavit “čisté přihlášení” (to se mi moc nezdá)?

<a href="http://localhost:8100/apex/f?p=100:101:0:BRANCH_TO_PAGE_ACCEPT:::P101_USERNAME,P101_PASSWORD:example,Letmein+1">My Application</a>

Celý formát URL je:

 f?p=App:Page:Session:Request:Debug:ClearCache:itemNames:itemValues:PrinterFriendly

V mém případě tedy asi:

http://apl.ab.czso.cz/pls/apex-apolo/f?p=119:1:0::::P2_APP_USER:lang4641

a “On New Instance” Applicatin Process musí být:

BEGIN
    APEX_CUSTOM_AUTH.POST_LOGIN (
        p_uname       => :P2_APP_USER,
        p_session_id  => V('APP_SESSION'),
        p_app_page    => :APP_ID||':1');
END;

SUBSTR do určitého znaku a od určitého znaku

REGEXP_SUBSTR('řetězec s / lomítkem','[^/]+',1,1)
Výsledkem je vše před lomítkem. Nebo:
REGEXP_SUBSTR('řetězec s / lomítkem','[^/]+',1,2)
Výsledkem je vše za lomítkem.

Jinak to jde i přes INSTR – před lomítkem:
NVL(SUBSTR(CIS_ZPRAVY, 0, INSTR(CIS_ZPRAVY, '/')-1), CIS_ZPRAVY)
Výsledkem je totéž (NVL je tam jen pro případ, žeby v CIS_ZPRAVY nebylo žádné lomítko).
Podobně za lomítkem:
NVL(SUBSTR(CIS_ZPRAVY, INSTR(CIS_ZPRAVY, '/')+1,4), CIS_ZPRAVY)

reference:
How to …
REGEXP_SUBSTR Function

Otevření URL adresy v nové záložce/ v novém okně

Vytvořit dynamickou akci s JS:

window.open('https://albatros.odok.cz/ODOK/eklep3.nsf/search.xsp?searchQuery=&P6_PID.', '_blank'); 

Obecně je to:

window.open('_link is here_', 'name'); 

kde name může mít tyto hodnoty:
_blank – URL is loaded into a new window. This is default
_parent – URL is loaded into the parent frame
_self – URL replaces the current page
_top – URL replaces any framesets that may be loaded

EMAIL – 2 způsoby

1. Přes speciální process

Zde je možno ale odpálit jen např. při On Load atd. v nejlepším případě přes AJAX request.

2. Přes Dynamik Action

DECLARE
    l_body      CLOB;
    l_body_html CLOB;
BEGIN
    l_body := 'Zpráva aplikace - Oddělení 2502'||utl_tcp.crlf||utl_tcp.crlf;
    l_body := l_body ||'  Pěkný den,'||utl_tcp.crlf;
    l_body := l_body ||'  Do aplikace Oddělení 2502 přidal uživatel '||:P6_OSOBA||' novou poznámku:'||utl_tcp.crlf||:P6_HLAVICKA||utl_tcp.crlf||:P6_TEXT;
    l_body_html := '<html><body>' || utl_tcp.crlf ||
                   '<h3>Zpráva aplikace - Oddělení 2502</h3><p>Do naší aplikace přidal uživatel '||:P6_OSOBA||' novou poznámku:<br/><br/> <h2>'|| utl_tcp.crlf ||:P6_HLAVICKA||'</h2>'||utl_tcp.crlf||'<i>'||:P6_TEXT||'</i><br/><br/>Aplikaci můžete spustit zde: http://apl-test.ab.czso.cz/pls/apex-apolotst/f?p=104 <br/><br/>'||
                   '<img src="https://dl.dropboxusercontent.com/u/55538373/CSU/logo-60.jpg" alt="Logo ČSÚ"></p>' || utl_tcp.crlf ||
                   '</body></html>';
    apex_mail.send(
        p_to       => 'jiri.kobzinek@czso.cz,jaroslav.kubinec@czso.cz,ondrej.martinovsky@czso.cz,jana.moravcova@czso.cz,jiri.novotny@czso.cz,jiri.oplt@czso.cz,jaroslav.ruzicka@czso.cz,petra.smutna@czso.cz,pavel.sykora@czso.cz,petr.tvrdon@czso.cz,jiri.vlk@czso.cz,petr.lang@czso.cz',   -- change to your email address
        p_from     => 'petr.lang@czso.cz', -- change to a real senders email address
        p_body     => l_body,
        p_body_html => l_body_html,
        p_subj     => 'Zpráva aplikace - Oddělení 2502');
END;
begin
wwv_flow_mail.push_queue(
   P_SMTP_HOSTNAME => '10.131.0.83',
   P_SMTP_PORTNO => '1677'
);
end;

Další příklady využiti API APEX_MAIL pro PLSQL verzi mailu:

https://docs.oracle.com/database/121/AEAPI/apex_mail.htm#AEAPI341

3. Zajímavé rozšíření EMAIL funkcí

ZDE
a posléze tedy ZDE

Náhrada IF EXISTS v PLSQL

V PLSQL na rozdíl od SQL nelze použít IF EXISTS. Je možné použít něco jako:

select count(n001) into ex from (select 
    n001
from apex_collections
where collection_name = 'OK' and n001 = num);
if ex != 0
then ....něco....;

Příklad – SZ_3 – (úřednická zkouška) – náhodné číslo otázky vyjma těch co už byly

declare
num number(3);
ex number(3);
begin
<<znovu>>
select round(dbms_random.value(1,(select max(cislo_otazky) from SZ_OTAZKY))) into num from dual;
select count(n001) into ex from (select 
    n001
from apex_collections
where collection_name = 'OK' and n001 = num);
if ex != 0
then goto znovu;
end if;
return num;
end;

Tabular report – zarovnání textu do prava

Element Attributes

style="text-align:right"

nebo např.

style="text-align:center"

IR report – šířka vlastní tabulky

V nastavení stránky:
CSS/Inline

.a-IRR-tableContainer {width: 355px}

případně s odsazením:

.a-IRR-tableContainer {
    width: 355px;
    margin-left: 150px}

IG report – šířka sloupců (noWrap)

Do definice stránky > do Execute when Page Loads zapsat JavaScript:

var igrid = apex.region ("IG_1").widget().interactiveGrid("getViews", "grid");
igrid.modelColumns.MSBER.noStretch = true;
igrid.modelColumns.EQA.noStretch = true;
igrid.modelColumns.PORCISREPR.noStretch = true;
igrid.modelColumns.ICO.noStretch = true;
igrid.modelColumns.RESICO.noStretch = true;
igrid.modelColumns.KODRESP.noStretch = true;
igrid.modelColumns.KODREPR3ZN.noStretch = true;
igrid.modelColumns.IKKD.noStretch = true;
igrid.view$.grid("refreshColumns");
igrid.view$.grid("refresh");

kde:
IG_1 – je ID interaktivního gridu,
MSBER, EQA,… – jsou názvy sloupců (napsal jsem to velkými písmeny a funguje to, nevím pokud zachovám velikost ?)
Funguje to u APEX 5.1.0 – u vyšších nevím ale víc je popsáno ZDE

Kopie tabulky do nové tabulky – procedura (backup)

create or replace procedure "PL_BACKUP"
is
    ex INT;
begin   
SELECT COUNT(*)
 INTO ex
 FROM ALL_TABLES
 WHERE OWNER || '.' || TABLE_NAME = 'PETR.PL_BACKUP';
IF ex > 0 THEN
 EXECUTE IMMEDIATE 'DROP TABLE PL_BACKUP';
END IF;
EXECUTE IMMEDIATE 'CREATE TABLE PL_BACKUP AS SELECT * FROM PL_DATA';
end;

Vytvořit Dynamic action, která vykoná “PL/SQL anonymus block”, ve kterém bude jen:
BEGIN název procedury; END;

Backup tabulky

create table BACKUP_TABULKA as SELECT * FROM TABULKA

Kopírování tabulky z jedné APEX databáze do druhé

V APEXU: V Object Browser – vytvořit DDL tabulky, indexu,trigeru,sequence – vytvořit script
V druhém APEXU: SQL Scripts- vytvořit- vložit kopii a spustit. (Tím se vytvoří tabulka bez dat.)
Pokud chci ještě zkopírovat data: V SQL-Developeru Tools/Database Copy…/zatrhnout jen objekt a data (ne DDL)/na další stránce odtrhnout ALL a zatrhnout jen Tabulky/vybrat tabulku/ Dokončit.
Bohužel kompletní kopírování v SQL-Developeru dělalo strašné věci. Taktéž vygenerování DDL dělalo problém, protože to zapsalo do DDL scriptu i WorkSpace

Interaktivní report s Dynamickým SQL vyzkoušeno- funguje

(Praktická ukázka v aplikaci CS104 Dante Plus)

Vytvořit process (before load header):

begin
  if apex_collection.collection_exists
        ( p_collection_name => 'IR_TEST' )
  then
    apex_collection.delete_collection
      ( p_collection_name => 'IR_TEST' );
  end if;

APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY(
p_collection_name => 'IR_TEST',
p_query => 'select 
       ICO IČO,
       KODREPR3ZN Reprezentant,
       KODRESP Respondent,
       PORCISREPR Pořadí,
       O487_R1_P1 Rep_5zn,
     


DECODE(&P3_ROK.,14, DECODE (&P3_QARTAL.,03,O488_R1_S1,06,O488_R2_S1,09,O488_R3_S1,12,O488_R4_S1),15,DECODE (&P3_QARTAL.,03,O488_R5_S1,06,O488_R6_S1,09,O488_R7_S1,12,O488_R8_S1)) Minule,
DECODE(&P3_ROK.,14, DECODE (&P3_QARTAL.,03,O488_R2_S1,06,O488_R3_S1,09,O488_R4_S1,12,O488_R5_S1),15,DECODE (&P3_QARTAL.,03,O488_R6_S1,06,O488_R7_S1,09,O488_R8_S1,12,O488_R9_S1)) Cena,
DECODE(&P3_ROK.,14, DECODE (&P3_QARTAL.,03,O488_R2_S2,06,O488_R3_S2,09,O488_R4_S2,12,O488_R5_S2),15,DECODE (&P3_QARTAL.,03,O488_R6_S2,06,O488_R7_S2,09,O488_R8_S2,12,O488_R9_S2)) Okres,
DECODE(&P3_ROK.,14, DECODE (&P3_QARTAL.,03,O488_R2_S3,06,O488_R3_S3,09,O488_R4_S3,12,O488_R5_S3),15,DECODE (&P3_QARTAL.,03,O488_R6_S3,06,O488_R7_S3,09,O488_R8_S3,12,O488_R9_S3)) Poznámka,
DECODE(&P3_ROK.,14, DECODE (&P3_QARTAL.,03,O488_R2_S4,06,O488_R3_S4,09,O488_R4_S4,12,O488_R5_S4),15,DECODE (&P3_QARTAL.,03,O488_R6_S4,06,O488_R7_S4,09,O488_R8_S4,12,O488_R9_S4)) Nová
      
  from PD_6070&P3_ROK.20&P3_ROK.&P3_QARTAL.@DANTE_PP_HK' );
  
end;

Select interaktivního reportu pak vypadá následovně:

Select *
From apex_collections
Where collection_name = 'IR_TEST'

S jednotlivými sloupci je nutno si pohrát asi nějak takto:

Do podmínek nasázet Never u těch, které nejsou k ničemu zapotřebí apřípadně použít fintu i s dynamicky přidělovanými názvy sloupců jako např.:

&P1_COL1. a &P1_COL2.   .....    použité v názvech příslušných sloupců

kde P1_COL1 … jsou skryté položky dynamicky naplňované názvy sloupců a jsou ( tady jsem něco nedopsal…asi).

Jinak jeden z návodů je např. zde:
http://oracleapplicationexpress.com/oracle-apex-interactive-report-based-on-plsql-function-46

Indikátor dlouhých procesu Prosím, čekejte … (Nevyzkoušeno)

Globální JavaScript:

function run_long_request (request, warnmsg) {
  if (!warnmsg || confirm(warnmsg)) {
    apex.submit({request:request,showWait:true});
  }
}

Přičemž request se využije pro specifické spuštění nějaké akce a warnmsg je text, který se má zobrazit.

Tlačítko bude vypadat nějak takto:

Action = Redirect to URL
URL Target = javascript:run_long_request('NACTI_DATA',
  'Are you sure you wish to approve this transaction?');

NACTI_DATA je nějaký request na základě kterého se něco děje.

Koláčový/sloupcový graf – SQL výraz – použito v “Úkoly RSIS”

Příklad – koláč vyplněné/nevyplněné datum v HOTOVO:

select 
decode(HOTOVO, null, 'f?p='|| :APP_ID ||':10:'|| :APP_SESSION, null) link,
decode(HOTOVO, null, 'Neukončeno', 'Hotovo' ) label,
count(*) value
from UK_ZAZNAMY_AKT
group by decode(HOTOVO, null, 'f?p='|| :APP_ID ||':10:'|| :APP_SESSION, null), decode(HOTOVO, null, 'Neukončeno', 'Hotovo')

Příklad sloupcový graf s rozdělenou hodnotou:

SELECT NULL LINK,
       (select ULOHA from UK_ULOHY where ID_ULOHA = ID) LABEL,
       count(HOTOVO) ano,
       count(*)-count(HOTOVO) ne
FROM  UK_ZAZNAMY_AKT
GROUP  BY ID_ULOHA

Zálohování (popř.přenos) aplikace a dat (příklad “ULOHY_STAV_X”)

  1. Data zálohovat v SQL Developeru přes DDL: Tools->Database Export->všechny typy, pak vybrat všechny soubory %ulohy_stav% a Dokončit
  2. asi to není tak úplně easy jak to vypadá – problém nastal pokud se zaškrtne, že exportovat i s datama – pak totiž nějak blbne kódování znakové sady (čeština)
  3. Pak je nutné asi DDL bez dat
  4. a data vyexportovat v APEXU do XML (SQL Workshop -> Utilities ->Data Workshop) a poté na druhé straně stejně natáhnout – pak to zvládá i češtinu
  5. Aplikaci zálohovat přes Application Builder->Application 186->Export/Import a zaškrtnout i Public a Privat saved reports.

Při přenosu do APEX5 se to takto nedařilo – zas pokus omyl – dopsat lepší postup !!

Vlastní autentifikace

http://allthingsoracle.com/custom-authentication-in-apex/

Autentifikace podle USER GROUP

Na vstupní stránce aplikace (tedy po loginu) vytvořit BRANCH to page xx (on Load before Header), který se provede za podmínky (PL/SQL Expression)
apex_util.current_user_in_group('zzz') != TRUE
, přičemž zzz je povolená skupina.
xx je stránka, která má template minimal (bez navigace) a je na ní napsáno něco jako “tady tě nechcem”.
Takto lze konec konců ochránit kteroukoli stránku, případně lze použít i v conditions pro jednotlivé items a regiony – tedy kontrolovat něco jako role.

Podmínka na USER

Condition: PL/SQL Expression
Expression 1::APP_USER != 'PETR' (v tomto případě pokud to nejsem já tak se provede)

JS – změna zobrazované hodnoty pole

Tam kde je v poli text Přítomnost v práci se bude zobrazovat text Přítomnost v práci < 180 min:

var plx = document.getElementsByTagName("td");
var i;
    for (i = 0; i < plx.length ;i++) {
     if (plx[i].textContent == "Přítomnost v práci") {plx[i].innerHTML = "Přítomnost v práci < 180 min"};
    }

JS – Vybarvení pole

$("td").each(function(){
 
var pole = $(this).text().substring(0,1);

   if(pole == "*"){
      $(this).css({"background-color":"#B6E0B9"});
   };
   if(pole == "#"){
      $(this).css({"background-color":"#E0B6C5"});
   };
});

Následující případ je pro formulářový report:

$("input").each(function(){
 
var pole = this.value.substring(0,1);

   if(pole == "*"){
      $(this).css({"background-color":"#B6E0B9"});
   };
   if(pole == "#"){
      $(this).css({"background-color":"#E0B6C5"});
   };
});

Pro formulářový report a pole, které není editovatelné (test na délku obsahu pole):

$("td").each(function(){
 
var pole = $(this).text();
var h = this.headers;
   if(pole.length != 5 && h == "REPREZENTANT5ZN" ){
      $(this).css({"background-color":"#E0B6C5"});
   };
});

JS – Vypnutí lišty v IR (DOM elementů v IR)

Vytvořit dynamickou akci (Page Load) a spuštění javascriptu:

document.getElementById("R78618328963584483_toolbar").style.visibility = "hidden";
document.getElementById("R78618328963584483_toolbar").style.display = "none";
document.getElementById("R78618328963584483_control_panel").style.visibility = "hidden";
document.getElementById("R78618328963584483_control_panel").style.display = "none";

V daném případě zmizí lišta a kontrolní panel filtrů …je nutné ale zjistit si to ID příslušného IR
To není nutné – stačí zadat do regionu příslušného IR STATIC ID a toto použít místo dynamicky přidělovaného (R78618328963584483). Čili např.:

document.getElementById("report_01_toolbar").style.visibility = "hidden";
document.getElementById("report_01_toolbar").style.display = "none";
document.getElementById("report_01_control_panel").style.visibility = "hidden";
document.getElementById("report_01_control_panel").style.display = "none";

kde v STATIC ID je uvedeno report_01

Šířka sloupce v reportu

In your report region, under Header and Footer, enter the following for Region Header

<style>
td[headers="NAME"] {
width:280px;
}
</style>

Do NOT forget: replace “NAME” with the column name you wish to give the width to.

Zrušení symbolu pro zavření dialogového okna (Close X)

!! Pozor toto CSS je nutné dát do stránky ze které se dialogové okno otevírá – jinak to nefunguje !!

button[Title="Close"] {
    display: none;
}

Bootstrap

  • Použít: Theme Bootstrap_02 – 126 (v tom je již do příslušných stránek vložen link na bootstrap – tedy minimálně určitě do No Tabs - No Sidebar)
  • V definicích jednotlivých Pages je link na bootsrap.css a ve stylu Body je definováno width-max:1024px což případně je možné změnit
  • Vložit link na JavaScript do Edit Application Properties>User Interface>JavaScript (např. https://dl.dropboxusercontent.com/u/55538373/B/bootstrap-3.0.0/dist/js/bootstrap.min.js)
  • U interaktivního reportu (aby fungovalo pole search) je nutné vložit do Region Header kód:
    <style>
    *, *:before, *:after {
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;
    box-sizing: content-box;}
    </style>

Důležité odkazy

Název Link
logo ČSÚ https://dl.dropboxusercontent.com/u/55538373/CSU/CSU-logo_120.png
logo ČSÚ – Apex-interně /i/logo1.png
rozcestník http://10.14.1.132/devel/Plang/B-rc.html
Bootstrap.css – interně /i/css/bootstrap.min.css

Jak spustit PL/SQL script z APEXU

  • Vytvořit proceduru (v SQL Developeru nebo přímo ve SQL Workshopu v APEXU)
    POZOR procedura vypad nějak takto:
create or replace procedure "CS104_TRANSFORMACE" as

k INT;
r VARCHAR(142);
....
BEGIN
k:=0;
.....
COMMIT;
END;
  • Zvolit si Event na který se má spustit (např. vytvořit tlačítko které to spustí)
  • Tlačítko musí vyvolat akci “Defined by dynamic action”
  • Vytvořit Dynamic action, která vykoná “PL/SQL anonymus block”, ve kterém bude jen:
    BEGIN název procedury; END;

Jak předat jméno uživatele přes URL !! externí aplikace INTRANET

Aplikaci vytvořit bez autentifikace (v shared commponents vytvořit příslušnou autentifikaci bez) a pak je možné volat nějakou stránku:

http://10.14.35.175:8080/apex/f?p=126:1:0:BRANCH_TO_PAGE_ACCEPT:::P1_X:abc

Tímto zápisem URL se naplní P1_X řetězcem “abc” a zároveň provede BRANCH, který je na stránce 1 definovaný.

Kalendář

Vytvářet jako “create page” (nedělat jako “create region” – pak je spousta práce s přidáním editace formuláře a lechce se na něco zapomene) – vytvoří se i formulářové stránky pro editaci a přidání.

CSS class událostí (modifikace podoby pole události)

standardní css APEXu:
apex-cal-green -red -blue -yelow -brown -orange ?

▶️ Když to chceš modifikovat tak např do HTML hlavičky:

<style> .fc .fc-event.apex-cal-green {border:2px solid red;} </style>

Nebo pokud chceš vytvořit vlastní styl:

<style> .fc .fc-event.test {border:2px solid red; background-color:#3AAB9A} </style>

-> pak do virtuálního pole css_class vkládáš vlastni

Kalendář pro rezervační systém Relax zóna -select 1den vs. více dnů

Zobrazovalo to stejně 2 dny i 1 den (…když se zadali 4 dny – udělalo to čáru jen přes 3 dny).
Řešení:
Source

select ID,
        MISTNOST,
       DATE_FROM,
CASE
when DATE_FROM = DATE_TO then DATE_TO
else DATE_TO + 1
end as DATE_TO,
       ZADAVATEL,
       HOST,
       POZ1,
       X1,
case MISTNOST
           when '0119a'    then 'apex-cal-green'
           when '0119b' then 'apex-cal-yellow'
           when '0119c'  then 'apex-cal-red'
       end as css_class

  from RELAX_ZONA

Srovnání dvou datových intervalů

V aplikaci Relax zóna

Validation->Typ: Not Exists

SELECT DATE_FROM, DATE_TO, MISTNOST
  FROM   relax_zona
  WHERE  DATE_FROM<= :P5_DATE_TO
  AND    DATE_TO>= :P5_DATE_FROM
  AND    MISTNOST = :P5_MISTNOST

Obecný příklad

Obecný příklad používa tuto tabulku:

CREATE TABLE dates_test (
  id         NUMBER,
  start_date DATE,
  end_date   DATE
);

INSERT INTO dates_test VALUES (1, TO_DATE('01-JAN-2012','DD-MON-YYYY'), TO_DATE('05-JAN-2012','DD-MON-YYYY'));
INSERT INTO dates_test VALUES (2, TO_DATE('05-MAR-2012','DD-MON-YYYY'), TO_DATE('08-MAR-2012','DD-MON-YYYY'));
INSERT INTO dates_test VALUES (3, TO_DATE('04-MAR-2012','DD-MON-YYYY'), TO_DATE('07-MAR-2012','DD-MON-YYYY'));
INSERT INTO dates_test VALUES (4, TO_DATE('06-MAR-2012','DD-MON-YYYY'), TO_DATE('09-MAR-2012','DD-MON-YYYY'));
INSERT INTO dates_test VALUES (5, TO_DATE('06-MAR-2012','DD-MON-YYYY'), TO_DATE('07-MAR-2012','DD-MON-YYYY'));
INSERT INTO dates_test VALUES (6, TO_DATE('04-MAR-2012','DD-MON-YYYY'), TO_DATE('09-MAR-2012','DD-MON-YYYY'));
COMMIT;

Procedura, která vyhodnotí překrytí datových intervalů
Vstupní parametry jsou začátek a konec:

CREATE OR REPLACE PROCEDURE date_clash (
  p_start_date IN DATE,
  p_end_date   IN DATE
)
AS
  l_count NUMBER(1) := 0;
BEGIN
  SELECT COUNT(*)
  INTO   l_count
  FROM   dates_test
  WHERE  start_date <= p_end_date
  AND    end_date   >= p_start_date
  AND    ROWNUM     = 1;
  
  IF l_count > 0 THEN
    RAISE_APPLICATION_ERROR(-20000, 'Dates range clashes with existing dates.');
  END IF;
END date_clash;

Trochu nechápu co tam dělá v tom WHERE podmínka ROWNUM = 1 . Zdá se mi to jako nesmysl.

IR – elegantní volba uložených reportů

(příklad je v package app “Sample Dynamic Actions” v menu “Refresh”)
Vytvořit ještě jeden report (neinteraktivní) s nějakým takovým selectem:

select 'visiblity: '||case when report_type in ('PRIMARY_DEFAULT', 'ALTERNATIVE_DEFAULT') then
            'Default'
        when report_type = 'PRIVATE' then
            'Private'
        else
            'Public'
    end card_subtext,
    report_id,
    coalesce(report_name, 'Primary Report') card_title,
    report_description card_text,
    apex_util.prepare_url('f?p='||:APP_ID||':17:'||:APP_SESSION||':::RP,17,RIR:P17_REPORT_ID:'||report_id) card_link
from apex_application_page_ir_rpt
where application_id = :APP_ID
    and page_id = :APP_PAGE_ID
    and (status = 'PUBLIC' or
        (status = 'PRIVATE' and application_user = :APP_USER))
    and report_type != 'SESSION'
order by 1 asc, 3, 4

Vložení- datum a čas do databáse

   DateTime d = System.now();
    return d;

Datum a čas

Pro ukládání informace o datumu resp. času slouží v SŘBD Oracle datový typ DATE. Problém je v tom, že tato informace musí být uložena v pevně definovaném formátu, který je parametrem serveru, jehož hodnotu většinou neznáme. Proto následující dotaz je chybný, protože porovnáváme hodnoty různých datových typů:

SELECT COUNT(*) FROM dual WHERE SYSDATE = ‘12.02.2007’;
Aktuální čas na serveru poskytuje SŘBD Oracle prostřednictvím pseudoproměnné SYSDATE. Pokud chceme zjistit, aktuální datum se shoduje se zadaným, musíme použít standardní konverzní funkci TO_CHAR():

SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE, ‘DD.MM.RRRR’) = ‘12.02.2007’;
Pokud budeme chtít zjistit aktuální datum (čas) na serveru, zadáme tento jednoduchý dotaz

SELECT SYSDATE FROM dual;
Pokud získáme jen datum, musíme dotaz upravit takto:

SELECT TO_CHAR (SYSDATE, ‘DD.MM.RRRR HH24:MI:SS’) FROM dual;
Pokud budeme chtít informaci o datu resp. času do databáze uložit, musíme použít další standardní konverzní funkci TO_DATE(), která pracuje přesně obráceně, tj. ze zadaného textového řetězce vytvoří informaci o datu resp. času. To platí též při zpracování časové informace. Např. chceme zjisiti název dne našeho data narození:

SELECT TO_CHAR(TO_DATE(‘04-05-1974’, ‘DD-MM-RRRR’), ‘Day’) den FROM dual;
Více informací o datumových a časových formátech funkcí TO_CHAR() a TO_DATE() se dozvíte v on-line nápovědě Oracle. Oddělovacími symboly může být téměř libovolný znak, nejčastěji se používá tečka, mezera, dvojtečka, …

Pokud chcete natrvalo nastavit formát datumu např. pro vkládání většího množství dat, je možné v rámci session přenastavit odpovídající systémovou proměnnou serveru takto:

ALTER SESSION SET NLS_DATE_FORMAT = ‘Day, DD. Month – RRRR’;
Pak bude vypadat výpis aktuálního datumu a času vypadat takto:

SQL> SELECT SYSDATE FROM dual;

SYSDATE
---------------------------
Pondělí, 12. Únor    - 2007

SQL> 

Proměnné v APEXu

Type Syntax Description
SQL :MY_ITEM Use standard bind variable syntax for items whose names are no longer than 30 characters. Use this syntax for references within a SQL query and within PL/SQL.
PL/SQL V('MY_ITEM') Use PL/SQL syntax to reference an item value using the V function.
See Also: Oracle Application Express API Reference
PL/SQL NV('MY_NUMERIC_ITEM') Use standard PL/SQL syntax referencing the numeric item value using the NV function.
See Also: Oracle Application Express API Reference
Static text (exact) &MY_ITEM. For static text or an exact substitution use the convention &ITEM_NAME followed by a period (.).

Vnitřní proměnné

APP_USER Syntax

Reference Type Syntax
Bind variable :APP_USER
PL/SQL V(‘APP_USER’)
Substitution string &APP_USER.

APP_ALIAS
APP_ID
APP_IMAGES
APP_PAGE_ID
APP_SESSION
APP_UNIQUE_PAGE_ID
APP_USER
AUTHENTICATED_URL_PREFIX
BROWSER_LANGUAGE
CURRENT_PARENT_TAB_TEXT
DEBUG
HOME_LINK
LOGIN_URL
IMAGE_PREFIX
Application Express SCHEMA OWNER
PRINTER_FRIENDLY
LOGOUT_URL
PROXY_SERVER
PUBLIC_URL_PREFIX
REQUEST
SQLERRM
SYSDATE_YYYYMMDD
WORKSPACE_IMAGES

ORACLE funkce

CURRENT_TIMESTAMP
LOCALTIMESTAMP

APEX – překlady textů

Dokumentace – návod


APEX API

APEX_CUSTOM_AUTH

ZDE
APEX_CUSTOM_AUTH.SET_USER – post authentication nastavení uživatele !

Úloha – ÚKOLY – tabulka úkolů

SELECT posledního záznamu k dané dvojici ULOHA x UKOL

select z.id_uloha, z.id_ukol, z.plan, z.hotovo, z.osoba, z.poznamka, z.datum
from (
select id_uloha, id_ukol, max(datum) maxdatum
from uk_zaznamy
group by id_uloha, id_ukol
 )
x inner join uk_zaznamy z on z.id_uloha = x.id_uloha and z.id_ukol = x.id_ukol and z.datum = x.maxdatum;

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s