Wielkość… ma znaczenie.

Oczywiście wielkość znaków. Ale też nie zawsze.

W przypadku baz oracle mamy nieco większą dowolność:

-- taki wpis będzie poprawny
select KOLUMNA from TABELKA
-- taki wpis też będzie poprawny
select kolumna from tabelka
-- a nawet taki
sElEcT KOlUMna fROm tAbElKa

Dla MySQL – niestety już nie, jeśli nazwiemy obiekt tAbElkA – to w każdym odniesieniu musimy użyć dokładnie takiej nazwy.

Czasem zdarza się, że nazywamy obiekt w sposób identyczny jak jedno ze słów kluczowych. Baza pozwala na stworzenie tabelki o nazwie SELECT albo WHERE – nie ma najmniejszego problemu.

Zapytanie w takim wypadku musi jednak wyglądać następująco:

SELECT * FROM "SELECT"

Użycie literału jest wymagane. Dodatkowo – w momencie kiedy ujmujemy nazwę w cudzysłów – wielkość znaków zaczyna mieć znaczenie także w bazie Oracle.

Identyczna sytuacja ma miejsce w przypadku warunków, poniżej dwa różne warunki:

-- warunek 1
select * from tabelka WHERE kolumna = 'Test'
-- warunek 2
select * from tabelka WHERE kolumna = 'test'

Oczywiście zawsze możemy napisać warunek, który zignoruje wielkość znaków (przykład dla baz Oracle):

select * from tabelka where upper(kolumna) = 'TEST'

Należy jednak pamiętać, że jeśli kolumna jest indeksowana – baza nie skorzysta z indeksu w momencie kiedy najpierw przekształcimy kolumnę na wielkie litery…

Pobranie wartości sekwencji w Oracle 10i

W ostatnim artykule o autonumerowaniu w Oracle pojawiła się następująca metoda pobrania kolejnej wartości sekwencji:

:new.ID:=TABELKA_SEQ.nextval;

To rozwiązanie zadziała jednak w bazach od wersji 11g. W starszych bazach spotkamy się z następującym komunikatem:
PLS-00357: Table,View Or Sequence reference ‚TABELKA_SEQ.NEXTVAL’ not allowed in this context

Ale możemy sobie wtedy poradzić z tym problemem następująco:

select TABELKA_SEQ.nextval into :new.ID from dual;

I wszystko będzie działać :)

Autonumerowanie w Oraclu?

Jeśli ktoś korzystał przykładowo z bazy MySQL i przesiadł się na Oracla – w pewnym momencie pewnie spyta: „a jak zrobić autonumerowanie klucza podstawowego”?
Otóż Oracle nie udostępnia takiej funkcjonalności samej w sobie. Ale możemy ją sobie napisać ;)

Zacznijmy od tabelki, która będzie miała klucz podstawowy, który chcemy automatycznie numerować:

 CREATE TABLE TABELKA
  (
    ID NUMBER(8) PRIMARY KEY,
    OPIS VARCHAR2(100))

Teraz musimy utworzyć sekwencję, która pozwoli nam pobierać kolejne wartości:

 CREATE SEQUENCE TABELKA_SEQ START WITH 1 INCREMENT BY 1

Warto przyjąć konwencję nazewniczą dla sekwencji: nazwa_tabeli_SEQ, pozwala to zachować w bazie porządek. Nasza sekwencja zacznie numerować od jedynki i będzie się zwiększać o jeden z każdym kolejnym rekordem.

I teraz tworzymy funkcjonalność, która zastąpi nam autonumerowanie: będzie to wyzwalacz, który za każdym razem gdy użytkownik spróbuje dodać wiersz bez klucza podstawowego – sam podstawi klucz korzystając z utworzonej sekwencji:

CREATE OR REPLACE TRIGGER TABELKA_PODSTAW_PK 
 BEFORE INSERT ON TABELKA
 FOR EACH ROW
    BEGIN
      :new.ID:=TABELKA_SEQ.nextval;
    END;

Pora na testy:

INSERT INTO TABELKA (OPIS) VALUES ('Wpis testowy')

Komunikat „1 rows inserted.” mówi nam, że wszystko przebiegło pomyślnie.

Bez triggera musielibyśmy każdorazowo używać sekwencji:

INSERT INTO TABELKA (ID, OPIS) 
VALUES (TABELKA_SEQ.nextval, 'Wpis testowy')

Dodatkowo jeśli nasz użyszkodnik spróbuje zrobić tak:

INSERT INTO TABELKA (ID, OPIS) 
VALUES (666, 'Wpis testowy')

Trigger automatycznie zamieni 666 na kolejną wartość sekwencji. W ten sposób w przyszłości można uniknąć błędu powtórzonej wartości.

Prawda, że tak jest prościej? :)

PS. Jeśli korzystasz z wersji niższej niż 11g – koniecznie zajrzyj tutaj

Szybkie tworzenie tabelek

Każdy kto choć trochę zajmował się DDLem na pewno zna polecenie CREATE TABLE. Czasem jednak zdarza się, że tablki tworzymy bardzo rzadko i tej składni nie pamiętamy – a akurat potrzebujemy na szybko utworzyć nową tabelę.

Dla tych użytkowników przydatnym mechanizmem jest tworzenie struktur z zapytań SQL. Przykładowo:

CREATE TABLE moja_tabelka AS
SELECT 
   'Tekst' AS NAGLOWEK_POLA_TEKST,
   0 AS NAGLOWEK_POLA_LICZBA,
   sysdate AS NAGLOWEK_POLA_DATA
FROM dual
WHERE 1=0 

Utworzy tabelę o nazwie „moja_tabelka” z taką strukturą danych jak zapytanie – pierwsza kolumna tekstowa, druga liczbowa i trzecia datowa. Nagłówki kolumn tabeli będą takie jak nadane aliasy w zapytaniu (są obowiązkowe w tym przypadku).

Warunek 1=0 w tym przypadku ma zwrócić zawsze fałsz – tak aby została utworzona tabela bez zawartości – sama struktura, do której później zaimportujemy dane.

Oczywiście w każdej chwili możemy posłużyć się jakimś gotowym zapytaniem z naszej produkcyjnej bazy, nie musimy korzystać z tabelki dual. Należy jednak pamiętać, że utworzona w ten sposób tabelka będzie z ustawieniami standardowymi oraz bez indeksowania.

Prawda, że prościej? :)