nehotový draft:
Prechod z MySQL na Oracle
- rozdily a problemy na ceste
obecne otazky:
- jake jsou kontexty pro praci s DB strojem?
pripojeni
session (=?=thread)
uzivatel
databaze
Last insert ID
MySQL:
- v MySQL je v rozhrani metoda, ktera vraci posledni
generovane IDecko z posledniho insertu, pro sloupec
s auto_incrementem
- SELECT LAST_INSERT_ID();
- je bezpecna v ramci session(?)
Oracle:
- cele je to emulovatelne sekvenci pro dany sloupec
- pak staci INSERT ... jmeno_sekvence.NEXTVAL
- nebo zavest trigger, co vklada hodnotu sam
- pro zjisteni posledniho ID pak je mozno
SELECT jmeno_sekvence.CURRVAL
(snad bezpecne v ramci sesny, pripadne radeji obalit do
transakce)
- pokud je potreba vylozene oddelit getlastid od insertu
napric transakcemi, je mozno vyuzit kontext package
a schovavat v nem hodnotu generovaneho ID
(pripadne i nejak CREATE CONTEXT... - ale asi zbytecne)
pak lze separatne volat SELECT package.vrat_id FROM DUAL
CREATE TABLE sample (
id INTEGER,
value VARCHAR(50),
PRIMARY KEY(id)
);
CREATE SEQUENCE sample_id_sequence
start with 1
increment by 1
nomaxvalue
;
CREATE TRIGGER sample_id_increment_trigger
before INSERT
ON sample
FOR each ROW
begin
SELECT sample_id_sequence.nextval INTO :new.id FROM dual;
end
;
/
Microsoft ma IDENTITY a SELECT @@IDENTITY (a dalsi dle kontextu)
PostgreSQL ma SERIAL; vyber IDecka neznam
---------------------------------------------------------
Case(in)sensitive navratove hodnoty
MySQL a Microsoft
- rozhrani vraci nazvy sloupcu ve stejnem tvaru v jakem byly
zalozeny, pro "rozumne" (napr. bez pomlcek) nazvy neni
potreba apostrofu (MySQL jako uvozovaci znak uziva apostrof
kod 96d; Microsoft???)
Oracle
- vraci sloupce nevytvorene v uvozovkach (jiny uvozovaci znak!)
zasadne velkymi pismeny
- je-li nazev v create velkymi, tak uvozovky neprekazeji (vraci
vse velkymi pismeny) -> jako by tam uvozovky nebyly
(ani v selektech nemusí být uvozovky)
- je-li ale nazev v uvozovkach a strida velika a mala pismena
(nebo staci jen mala), je treba ho pak vsude uvadet v uvozovkach(!),
jinak ho nezna. -> pro OCI pak zachovava velikosti pismen
- jinymi slovy je case-insensitive a pracuje s velkymi pismeny
PostgreSQL totez jako Oracle jen vse vraci naopak s malymi pismeny(!)
- jediná cesta, jak z toho ven, je aplikačně velikosti návratových
hodnot sjednotit (všechno malými nebo velkými); pro maximální přehlednost
je asi ideální mít v create skriptech i v samotných selektech také
všechno jednotně (nezávisle na interním ukládání db)
-> doporučení: všechny vlastní identifikátory česky (snižuje se
pravděpodobnost kolize s klíčovými slovy) [případně je rozumné
řešení aplikační prefix, např. HD_, při sdíleném kontextu s
jinými aplikacemi je možnost rozlišení; prefix mít možnost
konfigurovat, aby se dal zvolit až při instalaci] a malými písmeny
(lepší rozlišení oproti klíčovým slovům SQL, tedy v případě, že
SELECT, INSERT etc. je psáno velkými písmeny)
---------------------------------------------------------
Rozdilne "implementace" LIMIT (MySQL) a ROWNUM (Oracle)
---------------------------------------------------------
- omezená délka identifikátorů (např. název sekvence) na, tuším, 30 znaků
- nenazyvat tabulky (a asi ani sloupce) klicovymi slovy
napr. "session", "prior"
- Oracle nerozlišuje '' (prázdný řetězec) a NULL hodnotu, resp.
neumí prázdný řetězec, tj. např. nad sloupcem varchar not null nepovolí
vložit '' (MS, Postgre i MySQL to umí) a dokonce je to tak, že nad not null
sloupcem povolí default '' (či NULL). Také když bude default ' ', tak se při
vkládání '' tento default nepoužije, proč?
- při vytváření aliasů k tabulkám lze v MySQL (i MS a Postgre) psát "AS",
v Oracle nikoli, tj. psát vždy např. SELECT * FROM tabulka tab
a ne SELECT * FROM tabulka AS tab
- při zpracování datových typů jako CLOB a BLOB nelze jednoduše vkládat
přes SQL dotaz, při SELECTu to ještě lze nastavit parametrem (jinak OCI
vytvoří nad sloupcem objektový datový typ OCI-Lob a je nutno volat metodu
load(); práce s tímto objektem je v některých distribucích nestabilní!);
při INSERTu je však nutné hodnotu bindovat, poslat zvlášť SQL a až teprve
poté data
-> při použití těchto datových typů (LOB) nelze SQL dotazy psát nějak
rozumně jednotně; takže buď si vystačit s VARCHAR(4000) nebo se posunout
v abstrakci a úroveň výš a začít pomalu SQL opouštět úplně (případně
samozřejmě nějaký kompromis: např. parsování SQL dotazu na nějaký unikátní
klíč, který identifikuje LOB a volání zvlášť metody pro jeho update;
v MySQL pak třeba první volání cachovat a z druhého doplňovat data...)
? - escapovani ampersandu?
- jine funkce SYSDATE aka NOW() ci CURRENT_TIMESTAMP
- datovy typ DATE a manipulace s nim je v Oracle rozdilna (TO_DATE() etc.)
- nepouzivat MySQL fci PASSWORD
- fetchovani prazdneho vysledku hazi chyby? (fetch po INSERTu)
- nepsat středníky na konec SQL dotazů (alespoň pro OCI funkce v PHP)
ale zase naopak v PL/SQL bloku je středník nutný, pozor i na zpracovaní enterů
v PL/SQL blocích - nejlépe asi tam žádné nemít nebo užívat striktně Unix-like
- řádkový komentář -- se ukončí s dalším -- ?
pozn.: výběr systémových tabulek: SELECT * FROM dict
reference:
oprava dll knihovny (nestabilita pro clob->load() etc.)
http://pecl4win.php.net/ext.php/php_oci8.dll
srovnani vuci standardu:
http://troels.arvin.dk/db/rdbms/
auto_increment:
http://www.dbsvet.cz/view.php?cisloclanku=2006050501
http://www.jlcomp.demon.co.uk/faq/public_var.html
nacteni podrobnosti o strukture:
http://www.eveandersson.com/writing/data-model-reverse-engineering
prace s LOBy v PHPku:
http://www.oracle.com/technology/pub/articles/oracle_php_cookbook/fuecks_lobs.html
problemy obecne:
http://www.oracle.com/technology/tech/php/htdocs/php_troubleshooting_faq.html