Oracle random fact:Pomocí dbms_session.reset_package lze resetovat stav všech inicializovaných balíku v session;

PL/SQL programátor bloguje – vývoj aplikací pod databází Oracle

Tipy a triky pro PL/SQL a APEX


Přichází PL/SQL Developer verze 10

zadny komentar

Všichni známe velkou trojku – SQL Developer, TOAD a PL/SQL Developer. Osobně mám z nich nejraději právě PL/SQL Developera – více užitečný než SQL Developer a né tak připlácaný jako TOAD. Dnes jen krátká informace – vyšla jeho nová major verze s číslem 10. V rychlosti co je to obsahuje:

  • Jednodušší možnost přepínání edicí. Tedy místo ALTER SESSION již stačí klikat.
  • To samé platí pro Workspace – možnost výběru pod kterým Workspace chce developer pracovat. Tedy místo DBMS_WM.GoToWorkspace opět klikání.
  • Pokud napíšete jméno objektu delší než 30 znaků tak se podrhne červeně.
  • Párování závorek v editoru ať je kurzor před či za závorkou.
  • Export dat přímo do clipboardu (a krásně i verzi v jaké to chceme – txt/csv..).
  • Podpora chainů pro DBMS_SCHEDULER.
  • a něco hodně dalšího..

Celý list nových features lze vyčíst zde: http://www.allroundautomations.com/bodyplsqldev100.html

Myslím, že dobrý ;) Workspace/Edice asi moc programátorů nepouživá, ale spousta novinek se zajisté hodí. V listu jsem spoustu věcí nezmínil, takže je třeba si ti projet co je užitečné a co patří kočičkám. Enjoy!

Written by AZOR

April 3rd, 2014 at 9:51 pm

Posted in Novinky

Hinty z 11.2g (1/3) – CHANGE_DUPKEY_ERROR_INDEX

zadny komentar

Tento blog je online od února 2011 a je na čase udělat nějaké to čištění. Od uvedeného data se mi podařilo ve wordpressu úspěšně rozepsat a nezveřejnit několik postů. A co je možné bych rád zpětně pročistil, dopsal či bez návratu odstranil. Důvody nedopsání jsou různé od časových až po takové, kde jsem zjistil, že to tak jednoduché nebude – napříkad mi tu straší článek o tom jak založit tabulku. Moje představa byla založení tabulky pomocí insertů do datového slovníku pod SYSem, modifikace datových bloků, dopočítání kontrolních součtů atd. A musím říct, že jsem nebyl úspěšný – tabulku se mi daří téměř správně založit, funguje describe, select a vše vypadá korektně, ale insert se prostě nedaří (internal error oracle). A od té doby jsem se k tomu nedostal. Rozepsaných a slíbených postů, které jsem nezveřejnil bych se rád postupně zbavil.

Před dvěma lety jsem měl  plánu napsat post o hintu IGNORE_ROW_ON_DUPKEY_INDEX, který patří mezi ty specifické, které mění chování a nevěnují se optimalizaci. Oracle ho uvádí společně tyto hinty: CHANGE_DUPKEY_ERROR_INDEX, IGNORE_ROW_ON_DUPKEY_INDEX a RETRY_ON_ROW_CHANGE. A když už jsem v tom, rovnou je zkusme všechny ;. A začněme hned tím prvním CHANGE_DUPKEY_ERROR_INDEX.

CHANGE_DUPKEY_ERROR_INDEX – Umí změnit typ chyby v případě, že dojde k porušení unikátnosti. Konkrétně z ORA-001 udělá ORA-38911. K čemu je to dobré? Například pokud jsou nad tabulkou dva různé unikátní sloupce a jednoduššímu zjištění ve kterém ze zmíněných došlo k porušení unikátnosti. Hint lze použít v INSERT a UPDATE statementu. Takže příklad:

create table tbl_unique_hint_test as
select rownum as first_unique,
rownum as second_unique
from dual connect by level<6;

Synaxe je následující:

Tedy takto:

insert /*+CHANGE_DUPKEY_ERROR_INDEX(tbl_unique_hint_test(first_unique)) */ into tbl_unique_hint_test values (1,1);
SQL Error: ORA-38913: Index zadaný v tipu k indexu není platný

Vyhučelo na chybě. I když jde zadat pro zjištění unikátnosti místo indexu sloupce, tak není možné zadat sloupce na kterých není unikátní index/constraint. Dokumentace píše, že je to nutné toto omezení mín, ale nepíše co se stane když není – odpověď je tedy ORA-38913. Takže založení unikátního indexu nad sloupcem first_unique:

create unique index inx_unique_first on tbl_unique_hint_test(first_unique);

A opět test hintu:

create unique index inx_unique_first on tbl_unique_hint_test(first_unique);
unique index INX_UNIQUE_FIRST created.
insert /*+CHANGE_DUPKEY_ERROR_INDEX(tbl_unique_hint_test(first_unique)) */ into tbl_unique_hint_test values (1,1);
SQL Error: ORA-38911: nesplněna podmínka jedinečnosti (APEX_WORKOUT.INX_UNIQUE_FIRST)

Fajn, číslo chyby je jiné. Ale daleko zajímavější je to takto:

create unique index inx_unique_second on tbl_unique_hint_test(second_unique);
unique index INX_UNIQUE_SECOND created.
insert /*+CHANGE_DUPKEY_ERROR_INDEX(tbl_unique_hint_test(second_unique)) */ into tbl_unique_hint_test values (1,1);
SQL Error: ORA-38911: nesplněna podmínka jedinečnosti (APEX_WORKOUT.INX_UNIQUE_SECOND)

Nyní když jsou nad tabulkou unikátní dva indexy má nová chyba ORA-38911 přednost ORA-001. Tedy místo toho, aby příkaz vyhuče na duplikaci nad sloupcem FIRST_UNIQUE, protože hodnota 1 již tam je, vyhučí na ORA-38911 pro sloupec SECOND_UNIQUE.

Written by AZOR

March 23rd, 2014 at 12:05 am

Posted in Novinky

Workoutlog v APEXu – hezky od začátku #9 – zobrazení obrázku

zadny komentar

Pokračujme ve vytváření našeho workoutlogu, index předchozích dílů zde. Dneska to bude vcelku izolovaný díl – do reportu s WODy (cvičení – workout of day), pro který jsme částečně připravili editovací/vkládací formulář přidáme i obrázek. Způsobů jak toho docílit je opravdu mnoho. Jedna z nejjednodušších cest je udělat klasický report a že má být ve sloupci obrázek z (B)LOBu vcelku jednoduše nakonfigurovat. Velice podobně jako s ikonkou “edit”, což jsme použil hned v prvním dílu. Takže tentokrát úplně jinak – nebudeme zakládat žádnou stránku v konfiguraci APEXu, ale vrátíme stránku pomocí PL/SQL funkce a to samé z obrázkem – vytvoříme pl/sql, které bude obrázek číst z tabulky a vracet. Ještě to trošku odlehčím na začátek, v Crossfitu existují 2 základní typy WODů:

Hero WODs – Cvičení pojmenovaná po hrdinech. Typicky se jedná o amerického vojáka padlého v boji, případně hasiče, příslušníka SWAT apod. Ke každému hero wods by měl být tedy i obrázek daného hrdiny. Pro příklad na obrázku níže je Randy, člen SWAT, který zahynul v boji (cvičení 75x power snatch na čas).

Benchmark girl WODs – Cvičení pojmenovaná po ženách, nikoliv však, že by jej nezbytně musely cvičit jen ženy. A pokud se nepletu tak se to neváže k žádné konkrétní ženě. Nicméně zde se určitě obrázky budou hodit také, například Cindy (5 přítahů, 10 kliků, 15 dřepů – maximální počet kol za 20 minut(AMRAP)). Já si třeba představuji Cindy nějak takto:

A pak budou patrně nějaká další WOD a vlastní, ale proč jim také nepřiřadit, nějaký obrázek, že? Hlavně to děláme kvuli obrázkám žen pro benchmark girls ;)

To bylo na odlehčení a protože jsem se rozhodl psát to lehce formou tutoriálu (přecejen APEX v čechách moc nejede..) tak nejprve popis jak to asi bude fungovat. V Oracle je možné vytvořit funkci, kterou je možné provolat z browseru (či odkudkoliv). Funkci stačí vytvořit, nagrantovat jí a povolit její volání. Funkce může vracet výstup v html (package htp – v tom bude report – příští díl) a nebo případně jiný typ mime (image/jpg například pro obrázek).

Začněme s klasickým hello world/cindy:

create or replace procedure print_hello
is
begin
htp.p('hello world/cindy');
end;

Funkce je pod naším uživatelem APEX_WORKOUT, takže bez založení public synonyma jí lze provolat přes následující url:

http://localhost:8080/apex/APEX_WORKOUT.print_hello

Po otevření prohlížečem by se měla objevit chyba 404  – not found. Bez grantu to prostě nepůjde ;) Chce to grant pro uživatele anonymous.

grant execute on print_hello to anonymous;

Nyní už by to mohlo fungovat – respektive adresa http://localhost:8080/apex/APEX_WORKOUT.print_hello by měla přestat vracet error 404 (not found) a začít vracet 403 (not autorized). Co je ještě potřeba povolit je print_hello v proceduře wwv_flow_epg_include_mod_local, která je přímo ve schématu APEX. Procedura má jeden parametr, kterým je jméno funkce nebo procedury. Pokud je návrat true je přístup povolen, pokud je návrat false je přístup zamítnut. Mám APEX 4.2, tedy u mě je tato procedura v APEX_040200 schématu. Na co je dobré upozornit je, že funkce má připraven IF statement s listem, kam je možné vypsat povolené funkce (pozor na prefix schématu, velká a malá písmena apod). Ovšem na prvním řádku je napsáno return false; Na což se typicky nováček nachytá a řádek přehlídne a nevykomentuje. Po úpravách vypadá má funkce nějak takto:

create or replace
function wwv_flow_epg_include_mod_local(
procedure_name in varchar2)
return boolean
is
begin
if upper(procedure_name) in (upper('APEX_WORKOUT.print_hello')) then
return TRUE;
else
return FALSE;
end if;
end wwv_flow_epg_include_mod_local;

Kdybych měl vyjmenovat top chyby, pak by to bylo nevykomentování rádku return false; (odstranil jsem ho zde kompletně i ty komentáře od Oracle), nepočítání s prefixem schématu/název package. Velikost písmen a umístění funkce, tam kde být nemá (v APEX_040200 schématu). A to by mohlo být vše.  Takže po korektním přidání do wwv_flow_epg_inlude_mod_local už by mohla url fungovat.

To je hello world, a nyní by to chtělo proceduru, která bude vracet obrázek. Jako jeden parametr bude mít ID řádku (id_crossfit_wod_lov), který obrázek se má zobrazit. Bude číst z naší tabulky TBL_CROSSFIT_WOD_LOV. Dále musí vracet správný mime typ (image/jpeg). A pak už jen zbývá vytisknout na výstup LOB. Nacož se dá použít čtení LOBu po kouskách pomocí DBMS_LOB a tištění pomocí htp package nebo použít hotovou proceduru od Oracle z package WPG_DOCLOAD.

create or replace
PROCEDURE obrazek_wodu(p_image_id IN NUMBER)
AS
l_length NUMBER;
l_file_name VARCHAR2 (2000);
lob_loc BLOB;
BEGIN
/* Čtení BLOB obrázku z tabulky TBL_CROSSFIT_WOD_LOV */
SELECT picture, DBMS_LOB.getlength (picture)
INTO lob_loc, l_length
FROM TBL_CROSSFIT_WOD_LOV
WHERE id_crossfit_wod_lov = p_image_id;
/* vráceni správného mime typu a minimální hlavičky */
OWA_UTIL.mime_header ('image/jpeg', false);
HTP.p ('Content-length: ' || l_length);
OWA_UTIL.http_header_close;
/* vrácení dat obrázku */
WPG_DOCLOAD.download_file (lob_loc);
END obrazek_wodu;

Tedy by to chtělo zbavit se dlouhého jména, prefixu a udělat to tak jak se to dělat má – pomocí public synonyma:

create public synonym p_wod for apex_workout.obrazek_wodu;

Nagrantovat:

grant execute on p_wod to anonymous;

A opět přidat do wwv_flow_epg_inlude_mod_local:

create or replace
function wwv_flow_epg_include_mod_local(
procedure_name in varchar2)
return boolean
is
begin
if upper(procedure_name) in (upper('APEX_WORKOUT.print_hello'),'P_WOD') then
return TRUE;
else
return FALSE;
end if;
end wwv_flow_epg_include_mod_local;

A to je vše:

Příště udělejme PL/SQL funkci, která bude vracet stránku/report s WODama a někdy příště nebo dále bude možné na WOD kliknout a rovnou ho přidat do cvičení ;) A to už se budeme pomaličku blížit k něčemu na čem se dá stavět. Hébičkám zdar!

Written by AZOR

February 26th, 2014 at 1:16 pm

Workoutlog v APEXu – hezky od začátku #8 – editace wod definice (2)

zadny komentar

Link na předchozí díly. Pokračování z minula, kde jsme založili stránku s formulářem pro editaci TBL_CROSSFIT_WOD_LOV a TBL_CIRCLE_WORKOUT_DEF_SERIE. Ovšem z minulých dílů si bereme spoustu neřešených věcí, které chci pořešit nyní. Aktuálně největší pain jsou LOV a navázené entity. Tedy v tomto díle:

  • Pro pole “Is Default” je vhodné udělat číselník, ať to trošku vypadá – seznam s hodnotamy Ano/Ne
  • Pro pole “Crossfit Target Lov Id” číselník z tabulky tbl_crossfit_target_lov kam jsme v minulém díle nacpali data
  • Přejmenovat formulářové labely na něco rozumného
  • Vytvořit List of Values i pro podřaženou entitu TBL_CIRCLE_WORKOUT_DEF_SERIE

Task číslo 1. -  Pro pole Is Default je vhodné udělat číselník.

Po nalogování se dostaneme na editaci stránky Master Detail. U mě je to ID 14, ale pokud někdo následuje dostal pravděpodobně jiné číslo. Čísla stránek jdou za sebou, nicméně nějaké už jsem vytvořil a smáznul na zkoušku. Tedy Master Detail a editace fieldu P14_IS_DEFAULT.

Při editaci itemu hned v části Identification je na výběr typ. Záleží na typu a hodnotách, které chceme či nechceme umožnit. Zrovna pro binární hodnotu – je či není to defaulutní wod – je logicky na výběr spousta možností – od checkboxu, radio.. atd. Dokonce APEX pro hodnoty Yes/No nabízí vlastní typ. Vyberme Select List, je to příjemný interface a více použitelnější než checkbox či radio.

Dále v sekci Label jsem změnil nehezký text z “Is Default” na hezčejší “Oficiální WOD“. A ještě v sekci List of Values je třeba nadefinovat číselník. Je to velice podobné jako v Sieblu,  možnosti jsou dvě – statický a dynamický. Statický je pevný list hodnot, u kterého se předpokládá že se nebude měnit. Dynamický je napak takový, kde se čtou možnosti z uživatelských dat, tedy z tabulky. Pro toto pole jsou logické jen dvě hodnoty Yes/No, tedy statický. Do hodnoty List of values definition napíšeme :STATIC2:Ano;1,Ne;0. Static řiká, že jde o statické LOV, 2ka protože chceme aby byly v pořadí vytvoření (pak je bez dvojky – pořadí dle abecedy. Zde je to vcelku jedno). A po té se střídá zobrazená hodnota v listu – Ano s její hodnotou ve formuláří – 1. Každá další položka v listu je oddělena čárkou.

Task číslo 2. – Pro pole “Crossfit Target Lov Id” číselník z tabulky tbl_crossfit_target_lov

Z minula máme tabulku TBL_CROSSFIT_TARGET_LOV naplněnou nějakými daty. Z pohledu použití by toto měl být spíše statický list hodnot, ale v rámci cvičení jsem to navrhl jako tabulku a udělejme z toho tedy dynamické LOV. Po kliknutí na editování pole P14_CROSSFIT_TARGET_LOV_ID.

V části Identification opět vybereme Select List. V části Label jsem upravil pole Label na “Cíl cvičení“. A nyní to nejdůležitější – v části List of Values do pole List of Value Definitions:

select target_name, id_crossfit_target_lov from apex_workout.tbl_crossfit_target_lov order by target_name

Obyčejný select z databáze, jediné co je nutné si pamatovat je, že musí vracet dva sloupce s tím že první je textová hodnota zobrazovaná na stránce (target_name) a druhé je hodnota, která je skutečně ve formuláři a která jde do databáze (id_crossfit_target_lov – primární klíč). A ideáně ještě order by pro příjemnější zobrazení.

Task číslo 3. – Přejmenovat formulářové labely na něco rozumného

U každého z Itemů je fajn nastavit nějaký smysluplný label - edit na každém z itemů formuláře, sekce label, pole label. Udělejme něco takovéhleho:

  • P14_NAME – Jméno WODu
  • P14_IS_DEFAULT - Oficiální WOD
  • P14_CROSSFIT_TATGET_LOV_ID - Cíl cvičení
  • P14_PICTURE – Obrázek
  • P14_ROUNDS – Počet kol
  • P14_NOTE – Poznámka

Takže by to mohlo vypadat nějak takto:

Task číslo 4. -Vytvořit List of Values i pro podřaženou entitu TBL_CIRCLE_WORKOUT_DEF_SERIE

Na založení master záznamu WOD je to dostatečné. Ještě bohužel není možné založit k záznamu seznam kol cvičení, protože potřebují odkaz na záznam v tabulce TBL_TABATA_LOV nebo TBL_WORKOUT_LOV. Ve sloupci WORKOUT_OR_TABATA_LOV_ID může být odkaz do jedné nebo druhé tabulky (podobně to řeší Siebel), takže constraint který z mého modelu vygeneroval Oracle SQL Data Modeler nemá moc smysl:

ALTER TABLE TBL_CIRCLE_WORKOUT_DEF_SERIE DROP CONSTRAINT FK_CIRCLE_WORKOUT_DEF_SERIE;

Tím jsme se zbavili nutnosti mít nějaké záznamy v tabulkách TBL_TABATA_LOV a TBL_WORKOUT_LOV, ovšem stejně se bez toho neobejdeme, takže nějaká seed data zase:

INSERT INTO TBL_TABATA_LOV(NAME,ATTRIBUTE_1V,NOTE) VALUES ('Kliky v zátěžové vestě','+9,5kg','Obyčejné kliky v zátěžové vestě'); INSERT INTO TBL_TABATA_LOV(NAME,ATTRIBUTE_1V,NOTE) VALUES ('Dřepy','','Dřepy'); INSERT INTO TBL_TABATA_LOV(NAME,ATTRIBUTE_1V,NOTE) VALUES ('Angličáci','','Angličáci s výskokem'); commit;

To by byla TABATA a ještě obyčejná cvičení:

INSERT INTO TBL_WORKOUT_LOV(WORKOUT_DESCRIPTION,WEIGHT,BODY_WEIGHT_RELATIVE,TARGET,TIME_REST,TIME_REST_DEGRESSION,NOTE) VALUES ('Dřepy',null,1,15,null,null,null); INSERT INTO TBL_WORKOUT_LOV(WORKOUT_DESCRIPTION,WEIGHT,BODY_WEIGHT_RELATIVE,TARGET,TIME_REST,TIME_REST_DEGRESSION,NOTE) VALUES ('Kliky',null,1,10,null,null,null); INSERT INTO TBL_WORKOUT_LOV(WORKOUT_DESCRIPTION,WEIGHT,BODY_WEIGHT_RELATIVE,TARGET,TIME_REST,TIME_REST_DEGRESSION,NOTE) VALUES ('Přítahy',null,1,5,null,null,null); commit;

Nyní zpět do APEXu a opět přidání dynamického listu. Tentokrát do editace detailu (tabulka TBL_CIRCLE_WORKOUT_DEF_SERIE). Týká se to pole WORKOUT_OR_TABATA_LOV_ID, které opět zeditujem:

V Column Attributes vybereme v Display As hodnotu  Select List (query based LOV).

A ještě je třebas v sekci List of Values naplácnout SQL Select do pole List of Values Definition:

select label,val from ( select workout_description ||' '|| case when weight is not null then 'Váha:'||weight else null end || case when target is not null then 'Počet:'||target else null end || case when time_rest is not null then 'Odpočinek:'||time_rest else null end ||' (WORKOUT)' as label, id_workout_lov as val,1 from TBL_WORKOUT_LOV union all select name || ' (TABATA)', id_tabata_lov,2 from TBL_TABATA_LOV order by 3,2)

Spojení unionem all hodnoty z tabulek TBL_WORKOUT_LOV a TBL_TABATA_LOV. Zbytek je tak nějak na krásu.

Pro dnešek předposlední krok. Ještě chybí jeden List of Values a to pro pole IS_TABATA_OR_WORKOUT_ID. Takže do editace itemu IS_TABATA_OR_WORKOUT_ID v sekci Column Attributes v poli Display As vybrat tentokrát Select List (static LOV) a v sekci List of Values opět upravit List of Values Definition na:

STATIC2:Cvik;0,TABATA;1

A  poslední krok – v editaci stránky kliknout praým na TBL_CIRCLE_WORKOUT_DEF_SERIE Detail a vybrat Edit Report Attributes. A upravit labely ke sloupcům:

  • ID_CIRCLE_ORDER – Pořadí
  • WORKOUT_OR_TABATA_LOV - Cvičení
  • IS_TABATA_OR_WORKOUT_ID - Cvičení nebo TABATA
  • ATTRIBUTE_1v - Volné pole (varchar2)
  • ATTRIBUTE_1n - Volné pole (number)
  • Note - Poznámka

Takže po úpravách by mohl formulář na vkládní WOD vypadat nějak takto:

Ve formuláři na obrázku je vyplněno cvičení se jménem Chelsea. Přesně podle definice na Crossfit.com. Pro nyní je to vše, pro příště se nabízí dva logické kroky – report se definovanými WODy – tedy report nad tabulkou TBL_CROSSFIT_WOD_LOV a ideálně i výpis s definicí. A druhá věc, která je aktuálně chybí je možnost editace entit (TBL_TABATA_LOV a TBL_WORKOUT_LOV), kterou jsem v tomto článku dočasně obešel přímými inserty do databáze.

Written by AZOR

February 24th, 2014 at 12:54 am

Workoutlog v APEXu – hezky od začátku #7 – editace wod definice (1)

zadny komentar

Delší čas jsem se tomu nevěnoval, ale pokračuji ve vytváření workoutlogu v APEXu. Ze začátku jsem uváděl list dílů na začátku článku, což nebylo rozumné, protože patrně dojdu k tomu, že to bude mít opravdu hodně dílů. Tedy jsem vytvořil index-post, kde bud vést seznam dílů a na který se budu odkazovat. List předchozích dílů. Tenhle tutorál je ve stavu, kdy jsem je navržena datová vrstva, založen workspace, uživatelé a aplikace obsahuje následující stránky:

  • PAGE 1 -  main - zatím prázdná stránka
  • PAGE 2 – Master – TBL_WORKOUT - report kdy uživatel cvičil (Interactive report)
  • PAGE 3 –  Form on TBL_WORKOUT - editace hlavního záznamu cvičení
  • PAGE 101 – Login - automaticky generovaná stránka s loginem

Přemýšlel jsem o optimálním způsobu pokračování – na jednu stranu bych sem rád psal něco, co jde logicky za sebou na stranu druhou bych se co nejdříve rád přiblížil nějaké funkcionalitě, která je třebas i jen v obezené podobě použitelná. Aktuálně mi ze cvičení okouzlila Chelsea. Takže jsem se koukal na nějaké minimum, které je třeba implementovat, aby to šlo zaznamenávat a docela to dává smysl. Je na to potřeba možnost editace TBL_CIRCLE_WORKOUT_DEF_SERIE, kam mám v plánu ukládat definici cvičení – konkrétně pro Chelsea by tam měly být 3 rádky (jeden s 5 přítahama, druhý s 10 klikama a třetí s 15ti dřepy). A editaci nadřazné entity TBL_CROSSFIT_WOD_LOV, jako master záznam se jménem a parametrama. Obojí najednou se dá hezky vyřešit pomocí APEXového Master Detail Form. Takže začněme formulářem, kde je možné editovat WODy (workout of day):

Nalogujeme se do APEXu jako APEX_DEVELOPER a zeditujeme aplikaci WORKOUT_LOD (u mě 666):


A rovnou dáme “Create Page“. Nyní je na výběr typ stránky, kterou chceme vytvořit. Do tabulky je třebas umět zapisovat záznamy, takže FormNext.


Nyní je třebas nad čím či jak. Máme pod sebou dvě entity (TBL_CIRCLE_WORKOUT_DEF_SERIE a TBL_CROSSFIT_WOD_LOV), takže ideální je umět je zeditovat rovnou, tedy vybereme Master Detail Form a Next.


Nyní nás čeká vcelku rozsáhlý průvodce vytvořením stránek. První, co je požadováno je master tabulka, tedy:

  • Table/View Onwer: APEX_WORKOUT
  • Table/View Name: TBL_CROSSFIT_WOD_LOV
  • Defalutně se nepřidá LOB sloupec - nicméně obrázek uploadovat budeme chtít tedy do seznamu přidáme i PICTURE

A Next.


Nyní “detail” tabulka. Pro nás je to TBL_WORKOUT_CIRCLE_DEF_SERIE, ostatní default a Next.

Nyní APEX potřebuje vědět primární klíče pro obě tabulky:

  • APEX_WORKOUT.TBL_CROSSFIT_WOD_LOV – Zaškrtnout Select Primary Key Column(s) a pak ID_CROSSFIT_WOD_LOV.
  • APEX_WORKOUT.TBL_CIRCLE_WORKOUT_DEF_SERIE – Zaškrtnout Select Primary Key Column(s) a pak ID_CIRCLE_WORKOUT_DEF_SERIE

A zase Next..

Nyní je potřeba definovat pro obě tabulky z čeho se má generovat primární klíč. Prvně se vybírá pro master tabulku, tedy TBL_CROSSFIT_WOD_LOV.  Vybereme se sequence a pro touhle tabulku máme připravenou sequenci SEQ_ID_CROSSFIT_WOD_LOV. Next a po té následuje zase výběr zdroje primárního klíče pro tabulku TBL_CIRCLE_WORKOUT_DEFINITION, což je SEQ_ID_CIRCLE_WORKOUT_DEF_SERI.

A zase Next. Nyní je potřeba pořešit navigaci:

  • Include Master Row Navigator: No
  • Include Master Report: No (obojí si uděláme sami a hezečeji)

A zase Next. Dále je na výběr Layout, vybereme: Edit detail as tabular form on same page.

A Next. Ptát se to na atributy stránky (jméno čísla), necháme default a dáme zase Next. Vybrat Do not use Tabs a zase Next do posledního kroku, kde je summář:

A potvrdíme kliknutím na Create. Pak nás ideálně přivítá hláška o úspěšném vytvoření stránky. S možností jí rovnou otevřít. Problém je, že není možné založit záznam, protože je tu závislost na číselníku TBL_CROSSFIT_TARGET_LOV. Ve kterém nejsou žádná data. Interface a editace této entity počká, jedná se o číselník, který bude vcelku stabilní, takže naférovku inserty přímo do databáze:

insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (1,'For time','Na čas');
insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (2,'Numer of Rounds','Počet kol');
insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (3,'AMRAP','As many rounds as possible - maximální počet kol v časovém limitu');
insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (4,'OTM','Počet kol');
insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (5,'Complete','Prostě dokončit');
insert into tbl_crossfit_target_lov(id_crossfit_target_lov,target_name,note) values (6,'Kola v časovém limitu do selhání','Kola v časovém limitu do selhání');
commit;

Záznam již jde založit, ovšem zatím pouze pro master entitu, pro definici serie ještě nemáme data/lov číselníky. Nicméně už by to mohlo vypadat nějak takto:

Aktuálně jde pouze záznam založit. Teoreticky i zeditovat či smazat, ale aplikace zatím nemá nikde prolink ani nějak možnost otevřít již existující záznam. Lze toho docílit napsáním nějaké podobné url:

http://localhost:8080/apex/f?p=666:14:5516028830645::NO::P14_ID_CROSSFIT_WOD_LOV:2

Nemožnost editovat záznamy je zásadní nedostatek. Proklik ale bude až z nějakého reportu, kde bude možné vybírat si WODy k aktuálnímu cvičení a to určitě počká. Příště vylepšíme tenhle vkládací formulář. Hébičkám zdar!

Written by AZOR

February 23rd, 2014 at 6:07 am

Oracle Database 12c – Novinka #15 – Vylepšení SYS_CONTEXT

zadny komentar

Představení další novinky - byla vylepšena funkce SYS_CONTEXT. Dle kapitoly Changes in This Release for Oracle Database SQL Language Reference v manuálu Oracle® Database SQL Language Reference došlo k přidání nového namespace a to konkrétně SYS_SESSION_ROLES. Tedy už jsou nyní dva – USERENV a nová SYS_SESSION_ROLES, která umožňuje zjistit zda-li je role aktivní nebo neaktivní.  Příklad:

sqlplus / as sysdba;
create role developer_role;
grant developer_role to apex_workout;

Nalogování pod apex_workout a :

SET ROLE ALL EXCEPT DEVELOPER_ROLE;

Dříve to bylo zjstitelné z SESSION_ROLES pohledu. Takže spíše než novinka lehce jednodušší a rychlejší přístup. Co stojí za zmínku je, že v případě neexistující role funce vrací FALSE – tzn. to samé jako pro vypnutou roli.

Začal jsem schválně názvem kapitoly ve které se mluví o této novince. Ovšem již tam není zmínka o tom, že v SYS_CONTEXT byl vylepšen namespace USERENV a jsou tu nové atributy. Od pohledu mi připadal seznam atributů delší, takže jsem to začal zkoumat, jinak to však neni uvedeno jako změna, což je škoda, některé nové atributy jsou příjemné. Takže nové atributy:

  • CDB_NAME – jméno CDB, pokud to není multitenant container database tak NULL
  • CLIENT_PROGRAM_NAME - jméno klientského programu
  • CON_NAME - jméno containeru, pokud to není multitenant databáže tak DB_NAME
  • DB_SUPPLEMENTAL_LOG_LEVEL – vrací level v případě supplemental loggingu, jinak null. Možné hodnoty jsou stejné jako supplemental loggingu, tedy ALL_COLUMN, FOREIGN_KEY, MINIMAL, PRIMARY_KEY, PROCEDURAL a UNIQUE_INDEX
  • IS_APPLY_SERVER - pro Oracle Data Guard – true na apply server, jinak false
  • ORACLE_HOME – vrací ORACLE_HOME.  Sexy!
  • PLATFORM_SLASH - oddělovač adresářové cesty na dané platformě
  • SHEDULER_JOB - Y = je to spuštěno v dbms_scheduler,  N – není to spuštěno v dms_scheduler. Hodne sexy, předtím se to řešilo taky pomocí kontextu jestli to má nebo nemé bg_job_id či fg_job_id

U mě to vypadá nějak takto:

Asi bych čekal obrácené lomítko jako path-separator, tuhle instanci mam na Windows. Osatní sedí – nemám Oracle Data Quard, na téhle instanci ani supplemental logging a multitenant db na téhle instnaci také nemám. Hodně se mi líbí atributy SCHEDULER_JOB, CLIENT_PROGRAM_NAME, ORACLE_HOME a PLATFORM_SLASH. Všechno je pouze lehčí cesta než koukání do views (v$database, v$sesssion..). Pochopitelně mimo věcí souvisejících s  multitenant databází (CDB_NAME, CON_NAME) a PLATFORM_SLASH - zde mi nanapadá z hlavy žádné view ze kterého bych to byl schopen vytřískat. So, šikovná věcička.

Written by AZOR

February 22nd, 2014 at 2:12 am

Posted in Novinky

Oracle Database 12c – Novinka #14 – Truncate více (sub) partitions

zadny komentar

Oracle nově vylepšil ALTER TABLE statement a vylepšil práci s PARTITIONS (i se subky). Nově je možné v jendom příkazu pracovat s více PARTITONS najednou:

  • Přidat jednu/více range, list a system partitions do tabulky
  • Pridat jednu/více range či list subpartitions do partition
  • Rozdělit partition či subpartition na dvě a více partitons či subpartitions – týká se list a range
  • Spojit partition či subpartition na dvě a více partitons či subpartitions – týká se list a range
  • Truncatovat jednu nebo více partition nebo subpartition
  • Truncatovat jednu nebo více partition nebo subpartition

Řadím do spíše do těch užitečnějších vylepšení.  Na zkoušku, že to funguje a na zapamatování, že něco takového je nyní možné – truncate, to je nejednodušší ;) Nicméně implementace a syntaxe je velice podobná pro všechny tyto změny, na 11.2g to vypadalo takto:


Nyní na 12.1c:

Tedy list oddělený čárkama. Takže na zkoušku nějaká tabulka s partišnama a truncate více partitions najednou. Ze studijních důvodů použiji system partitions ;) – těch způsobů jak tabulku partišnovat (top-level) je 7 (co, vím – tzn. minimálně), ale typicky se mluví jen o těch hash, list, range. Zrovna systémové partišnování není moc známé (a ani používané).

CREATE TABLE TBL_TEST_TRUNCATE (slova VARCHAR2(20))
PARTITION BY SYSTEM (
PARTITION p1,
PARTITION p2,
PARTITION p3
);

INSERT INTO TBL_TEST_TRUNCATE PARTITION(p1) VALUES ('Lupíčky');
INSERT INTO TBL_TEST_TRUNCATE PARTITION(p2) VALUES ('Hébičky');
INSERT INTO TBL_TEST_TRUNCATE PARTITION(p3) VALUES ('Kulíškové');
INSERT INTO TBL_TEST_TRUNCATE PARTITION(p2) VALUES ('Kozy');
commit;

A truncate:

ALTER TABLE TBL_TEST_TRUNCATE TRUNCATE PARTITION p1,p2;

Možná za zmínku stojí napsat, že je možné psát TRUNCATE PARTITION i TRUNCATE PARTITIONS. Ať s nebo bez s je možné truncatovat jednu čí více partitions. Oracle tomu řiká “sytnax clarity” a doporučení je psát to bez s nakonci pokud truncatuju jednu a opačně.

Written by AZOR

February 19th, 2014 at 12:46 pm

Posted in Novinky