Oracle po 18c dorzucil sporo funkcji, ktore ulatwiaja codzienna prace z baza - zebralismy najwazniejsze zmiany z 19c, 21c i 23ai razem z dzialajacymi przykladami kodu, zeby nie trzeba bylo ich szukac po dokumentacji.
Jeśli ostatni raz pisałeś kod pod Oracle 12c albo 18c, to baza danych, którą znasz, zmieniła się bardziej, niż myślisz. Przez ostatnie lata Oracle dorzucił do języka SQL i PL/SQL rzeczy, na które programiści czekali latami: prawdziwy typ BOOLEAN, SELECT bez FROM, natywny typ JSON, JavaScript wykonywany wewnątrz bazy, makra SQL, a w 23ai – typ VECTOR i wyszukiwanie semantyczne pod AI. Ten artykuł to przegląd najważniejszych nowości wprowadzonych po 18c, wersja po wersji, z konkretnym kodem, który możesz wkleić i uruchomić.
Mapa wersji: 18c → 19c → 21c → 23ai
Najpierw porządek w nazewnictwie, bo Oracle sam namieszał. Po 18c numeracja przestała oznaczać "co roku jedna duża wersja" i podzieliła się na dwa nurty:
- 19c – Long Term Release. Stabilna, produkcyjna, z najdłuższym wsparciem. To na niej do dziś stoi większość systemów w bankach i telco.
- 21c – Innovation Release. Krótkie wsparcie, poligon nowych funkcji (natywny JSON, makra SQL, JavaScript w bazie, blockchain tables). Świetna do nauki i PoC, rzadziej na produkcję.
- 23ai – nowy Long Term Release (początkowo wydany jako "23c Free", potem przemianowany na 23ai, bo flagową funkcją stało się AI Vector Search). To tu wlądowała większość długo wyczekiwanych usprawnień składni: prawdziwy typ BOOLEAN, SELECT bez FROM, IF EXISTS w poleceniach DDL, GROUP BY po aliasie kolumny, typ VECTOR oraz JSON Relational Duality – każde z działającym przykładem w dalszej części artykułu.
Uwaga o 20c: wersja 20c nigdy nie wyszła jako produkt on-premise – była tylko preview w chmurze. Część funkcji "z 20c", o których pisano w sieci, faktycznie trafiła dopiero do 21c lub 23ai.
Oracle 19c – dojrzała stabilizacja
19c to nie rewolucja składni, tylko automatyzacja i wydajność. Cztery rzeczy, które realnie zmieniają codzienną pracę z bazą:
LISTAGG z DISTINCT – koniec sztuczek na duplikaty
Przed 19c LISTAGG nie znało słowa DISTINCT. Żeby skleić tylko unikalne wartości, trzeba było albo odsiać duplikaty osobnym podzapytaniem, albo posłużyć się brzydkim trikiem z REGEXP_REPLACE na gotowym stringu:
-- Przed 19c, wariant 1: duplikaty odsiane wczesniej, w podzapytaniu
SELECT department_id,
LISTAGG(job_id, ', ') WITHIN GROUP (ORDER BY job_id) AS stanowiska
FROM (SELECT DISTINCT department_id, job_id FROM employees)
GROUP BY department_id;
-- Przed 19c, wariant 2: trik regexem usuwajacy powtorzenia w gotowym stringu
SELECT department_id,
REGEXP_REPLACE(
LISTAGG(job_id, ', ') WITHIN GROUP (ORDER BY job_id),
'([^,]+)(, \1)+', '\1') AS stanowiska
FROM employees
GROUP BY department_id;
Od 19c to jedno słowo – DISTINCT prosto w LISTAGG, bez podzapytań i trików:
-- 19c: DISTINCT bezpośrednio w LISTAGG
SELECT department_id,
LISTAGG(DISTINCT job_id, ', ')
WITHIN GROUP (ORDER BY job_id) AS stanowiska
FROM employees
GROUP BY department_id;
-- DEPARTMENT_ID STANOWISKA
-- 50 SH_CLERK, ST_CLERK, ST_MAN
-- 80 SA_MAN, SA_REP
Automatic Indexing – baza sama dobiera indeksy
Jedna z największych nowości 19c (Enterprise Edition oraz Autonomous Database). Co kilkanaście minut baza analizuje rzeczywiste obciążenie, wykrywa zapytania, którym brakuje indeksu, i zakłada kandydujące indeksy jako niewidoczne (invisible) – optymalizator korzysta z nich tylko w trybie testowym. Potem porównuje wydajność tych samych zapytań z indeksem i bez niego: jeśli indeks realnie pomaga, publikuje go (staje się widoczny dla wszystkich), a jeśli nie – odrzuca. Automatycznie utworzone indeksy poznasz po nazwie zaczynającej się od SYS_AI_ i fladze AUTO = 'YES'.
Sterujesz tym jedną procedurą z pakietu DBMS_AUTO_INDEX – zwykle najpierw w trybie raportowym, a po sprawdzeniu przełączasz na produkcyjny:
-- Tryb testowy: baza TYLKO rekomenduje, nic nie tworzy
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'REPORT ONLY');
-- Tryb produkcyjny: automat sam tworzy i publikuje pomocne indeksy
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'IMPLEMENT');
-- Ogranicz automat do wybranych schematow (np. tylko HR i SALES)
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'HR', TRUE);
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'SALES', TRUE);
-- Ile dni trzymac nieuzywane auto-indeksy, zanim baza je skasuje
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_AUTO', '30');
Gdzie podejrzeć, co automat utworzył? Auto-indeksy leżą w tych samych widokach słownikowych co zwykłe, tylko z flagą AUTO = 'YES' – do tego masz widok konfiguracji i gotowy raport tekstowy:
-- Lista indeksow utworzonych automatycznie (nazwy SYS_AI_...)
SELECT owner, index_name, table_name, auto, visibility, status
FROM dba_indexes
WHERE auto = 'YES'
ORDER BY owner, table_name;
-- Biezaca konfiguracja automatu (tryb, schematy, retencja)
SELECT parameter_name, parameter_value
FROM dba_auto_index_config;
-- Pelny raport za ostatnia dobe: co utworzono/odrzucono,
-- o ile przyspieszyly zapytania, ile zajely miejsca
SELECT DBMS_AUTO_INDEX.REPORT_ACTIVITY(
SYSTIMESTAMP - 1, SYSTIMESTAMP) AS raport
FROM dual;
Tak to wygląda na żywej bazie. Sam widok konfiguracji podejrzysz na każdej edycji – poniżej realny zrzut dba_auto_index_config ze świeżej instancji. Domyślnie automat jest wyłączony (AUTO_INDEX_MODE = OFF), nieużywane auto-indeksy baza trzyma 373 dni, a raporty 40 dni:
SQL> SELECT parameter_name, parameter_value FROM dba_auto_index_config;
PARAMETER_NAME PARAMETER_VALUE
-------------------------------------- ----------------
AUTO_INDEX_COMPRESSION OFF
AUTO_INDEX_DEFAULT_TABLESPACE
AUTO_INDEX_INCLUDE_DML_COST ON
AUTO_INDEX_MODE OFF
AUTO_INDEX_REPORT_RETENTION 40
AUTO_INDEX_RETENTION_FOR_AUTO 373
AUTO_INDEX_RETENTION_FOR_MANUAL
AUTO_INDEX_SCHEMA
AUTO_INDEX_SPACE_BUDGET 50
AUTO_INDEX_TABLE
10 rows selected.
Uwaga licencyjna. Samo włączenie automatu (AUTO_INDEX_MODE = IMPLEMENT) i powstające indeksy SYS_AI_ to funkcja Enterprise Edition oraz Autonomous Database. Na Standard Edition i w bezpłatnym Oracle Database Free ta sama procedura zwraca błąd:
SQL> EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'IMPLEMENT');
BEGIN DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'IMPLEMENT'); END;
*
ERROR at line 1:
ORA-40216: feature not supported
Lista utworzonych indeksów. Na wspieranej platformie (Autonomous Database lub Exadata) ta sama procedura przechodzi i automat realnie zakłada indeksy. Auto-indeks poznasz po prefiksie SYS_AI_ i fladze AUTO = 'YES'; kolumna VISIBILITY pokazuje etap weryfikacji (najpierw INVISIBLE – optymalizator testuje indeks w ukryciu, a po potwierdzeniu zysku VISIBLE), zaś STATUS = VALID oznacza indeks gotowy do użycia. Oto autentyczny przebieg z Autonomous Database 19c: po przełączeniu na IMPLEMENT i cyklu automatu nad naszym obciążeniem (tabela 1 mln wierszy, powtarzane zapytania po nieindeksowanej kolumnie KLIENT_ID) powstał jeden indeks. Na Standard Edition i w Oracle Free to samo zapytanie zwraca brak wierszy – automat tam nie działa:
SQL> SELECT owner, index_name, table_name, auto, visibility, status
FROM dba_indexes WHERE auto = 'YES';
OWNER INDEX_NAME TABLE_NAME AUTO VISIBILITY STATUS
----- -------------------- ---------- ---- ---------- ------
ADMIN SYS_AI_99zjgtmjmwt9a ZAMOWIENIA YES VISIBLE VALID
Raport aktywności. Skoro indeks już jest, REPORT_ACTIVITY daje gotowe podsumowanie dla administratora: które indeksy powstały, o ile procent przyspieszyły konkretne zapytania, ile zajęły miejsca i które kandydatury baza odrzuciła jako nieprzydatne – bez ręcznego zgadywania. Z tego samego przebiegu:
SQL> SELECT DBMS_AUTO_INDEX.REPORT_ACTIVITY() FROM dual;
GENERAL INFORMATION
-------------------------------------------------------------------------------
Activity start : 23-JUN-2026 16:04:28
Activity end : 23-JUN-2026 17:04:28
Executions completed : 1
SUMMARY (AUTO INDEXES)
-------------------------------------------------------------------------------
Index candidates : 1
Indexes created (visible / invisible) : 1 (1 / 0)
Space used (visible / invisible) : 13.63 MB (13.63 MB / 0 B)
SQL statements verified : 2
SQL statements improved (improvement factor) : 2 (389.5x)
Overall improvement factor : 389.5x
INDEX DETAILS
-------------------------------------------------------------------------------
| Owner | Table | Index | Key | Type |
| ADMIN | ZAMOWIENIA | SYS_AI_99zjgtmjmwt9a | KLIENT_ID | B-TREE |
VERIFICATION DETAILS
-------------------------------------------------------------------------------
SQL ID : 7p9s5mbztk5zn
SQL Text : SELECT SUM(KWOTA) S FROM ZAMOWIENIA
WHERE KLIENT_ID = MOD(:B1*13,50000)
Improvement Factor : 220.17x
Z raportu czytasz wprost: 1 kandydat, 1 utworzony indeks (13,63 MB), 2 zapytania zweryfikowane i poprawione, B-drzewo na KLIENT_ID – ze współczynnikiem poprawy 389,5x. To samo zadanie z czasem usuwa też nieużywane auto-indeksy i samo wycofuje zmiany, które nie przyniosły poprawy – bez udziału administratora. Same zapytania kontrolne (widoki słownikowe + REPORT_ACTIVITY) są identyczne na każdej edycji – różni się tylko to, czy automat ma prawo działać.
Real-Time Statistics – statystyki zbierane w locie
Do tej pory statystyki optymalizatora robił DBMS_STATS w oknie nocnym, a między zbieraniami potrafiły się "zestarzeć". W 19c (Enterprise Edition na Exadata) baza dozbiera podstawowe statystyki automatycznie podczas zwykłych operacji INSERT / UPDATE, dzięki czemu optymalizator ma świeższe dane bez czekania na nocny job.
SQL Quarantine – kwarantanna zabójczych zapytań
Gdy Resource Manager zabije zapytanie za zbyt żarłoczne zużycie CPU/IO, 19c zapamiętuje jego plan wykonania i "kwarantannuje" go – kolejne uruchomienie tego samego, kosztownego planu jest odrzucane od razu, bez ponownego zarżynania serwera.
-- Podgląd skwarantannowanych planów
SELECT name, plan_hash_value, last_executed
FROM dba_sql_quarantine;
-- Ręczne usunięcie konfiguracji kwarantanny
EXEC DBMS_SQLQ.DROP_QUARANTINE('SQL_QUARANTINE_abc123');
Oracle 21c – poligon dla programistów
21c to wersja, w której Oracle przestaje być "tylko relacyjną bazą". Pojawia się natywny JSON, JavaScript w środku silnika, makra SQL i tabele kryptograficzne. Nawet jeśli nie wdrożysz 21c na produkcji, warto znać te funkcje – większość z nich jest dostępna też w 23ai.
Natywny typ JSON – szybciej niż CLOB
Wcześniej JSON trzymaliśmy w VARCHAR2 / CLOB z ograniczeniem IS JSON. 21c wprowadza dedykowany typ JSON, w którym dokument jest parsowany raz, przy zapisie – odczyt i aktualizacja są wielokrotnie szybsze.
CREATE TABLE zamowienia (
id NUMBER GENERATED ALWAYS AS IDENTITY,
dane JSON -- natywny typ, nie VARCHAR2/CLOB
);
INSERT INTO zamowienia (dane) VALUES (
'{"klient":"Nowak Sp. z o.o.","pozycje":[{"sku":"A1","ilosc":3}],"kwota":1499.00}'
);
-- Dot-notation prosto po polach JSON, bez funkcji:
SELECT z.dane.klient AS klient,
z.dane.kwota.number() AS kwota
FROM zamowienia z
WHERE z.dane.kwota.number() > 1000;
SQL Macros – reużywalne fragmenty zapytań
Makra SQL to funkcje, które zamiast wartości zwracają fragment tekstu SQL wstawiany do zapytania w czasie parsowania. Działają jak szablon, ale bez narzutu wywołania funkcji PL/SQL dla każdego wiersza. Są dwa rodzaje: SCALAR (do SELECT/WHERE) i TABLE (do FROM).
-- MAKRO SKALARNE: czytelny warunek "między datami"
CREATE OR REPLACE FUNCTION between_dates(p_col DATE, p_from DATE, p_to DATE)
RETURN VARCHAR2 SQL_MACRO(SCALAR)
IS
BEGIN
RETURN 'p_col BETWEEN p_from AND p_to';
END;
/
SELECT * FROM employees
WHERE between_dates(hire_date, DATE '2020-01-01', DATE '2020-12-31');
-- MAKRO TABELARYCZNE: parametryzowany "TOP N" jako źródło w FROM
CREATE OR REPLACE FUNCTION top_n_salary(p_n NUMBER)
RETURN CLOB SQL_MACRO
IS
BEGIN
RETURN 'SELECT employee_id, last_name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST p_n ROWS ONLY';
END;
/
SELECT * FROM top_n_salary(5);
JavaScript w bazie – pakiet DBMS_MLE
Multilingual Engine (MLE) pozwala uruchomić kod JavaScript wewnątrz bazy, z dwukierunkową wymianą danych z PL/SQL i SQL. Idealne, gdy masz gotową logikę w JS albo potrzebujesz przetwarzania, które w SQL jest niewygodne.
DECLARE
l_ctx DBMS_MLE.context_handle_t;
l_source CLOB;
BEGIN
l_ctx := DBMS_MLE.create_context();
l_source := q'~
// JavaScript wykonywany wewnątrz Oracle
const result = session.execute(
"SELECT last_name FROM employees WHERE rownum <= 3");
let names = [];
while (result.rows && result.rows.length) {
names = result.rows.map(r => r[0]);
break;
}
soda; // dostęp do kolekcji JSON także z JS
console.log("Pracownicy: " + names.join(", "));
~';
DBMS_MLE.eval(l_ctx, 'JAVASCRIPT', l_source);
DBMS_MLE.drop_context(l_ctx);
END;
/
Blockchain Tables – tabele, których nie zmienisz
Tabele typu blockchain pozwalają wyłącznie na INSERT. Każdy wiersz jest kryptograficznie połączony (hash) z poprzednim – próba modyfikacji lub usunięcia historii jest wykrywana. Świetne do logów audytowych, które muszą być niepodważalne (compliance, AML, RODO).
CREATE BLOCKCHAIN TABLE audyt_operacji (
id NUMBER,
operacja VARCHAR2(100),
uzytkownik VARCHAR2(50),
ts TIMESTAMP
)
NO DROP UNTIL 31 DAYS IDLE -- nie skasujesz tabeli od ręki
NO DELETE LOCKED -- wierszy nie da się usunąć
HASHING USING "SHA2_512" VERSION "v1";
-- Działa tylko INSERT; UPDATE/DELETE = błąd ORA-05715
Pokrewną funkcją są Immutable Tables (też 21c) – niezmienne tabele bez całego łańcucha hashy, gdy potrzebujesz tylko "insert-only" bez pełnej kryptografii blockchaina.
Oracle 23ai – największy skok dla developera
To wersja, na którą programiści czekali najdłużej. 23ai usuwa irytujące różnice między Oracle a PostgreSQL/MySQL i dorzuca rzeczy, których w ogóle nie było. Przejdźmy przez nie z kodem.
Prawdziwy typ BOOLEAN
Koniec z CHAR(1) i NUMBER(1) udającymi logikę. 23ai ma natywny BOOLEAN w SQL – w kolumnach, warunkach i INSERT. Akceptuje też wartości tekstowe jak 'yes'/'no', 'on'/'off', 1/0.
CREATE TABLE uzytkownicy (
id NUMBER GENERATED ALWAYS AS IDENTITY,
login VARCHAR2(50),
aktywny BOOLEAN, -- natywny typ logiczny
archiwum BOOL DEFAULT FALSE -- BOOL = synonim BOOLEAN
);
INSERT INTO uzytkownicy (login, aktywny, archiwum) VALUES
('anowak', TRUE, FALSE),
('jkowal', 'yes', 'no'), -- wartości tekstowe też działają
('bzych', 1, 0);
SELECT login FROM uzytkownicy WHERE aktywny; -- bez = TRUE
IF [NOT] EXISTS w DDL
Skrypty migracyjne bez blokuów BEGIN ... EXCEPTION WHEN OTHERS. 23ai pozwala warunkowo tworzyć i usuwać obiekty:
DROP TABLE IF EXISTS logi_tymczasowe;
CREATE TABLE IF NOT EXISTS slownik_statusow (
kod VARCHAR2(10) PRIMARY KEY,
opis VARCHAR2(100)
);
CREATE INDEX IF NOT EXISTS idx_status_opis ON slownik_statusow(opis);
GROUP BY po aliasie (i pozycji) kolumny
Klasyczny zgrzyt dla osób znających PostgreSQL: w Oracle nie dało się grupować po aliasie z SELECT. W 23ai już można – po aliasie albo po numerze pozycji:
SELECT TRUNC(hire_date, 'MM') AS miesiac,
COUNT(*) AS liczba
FROM employees
GROUP BY miesiac -- alias zamiast powtarzania TRUNC(...)
ORDER BY miesiac;
-- Można też po pozycji:
SELECT department_id, job_id, COUNT(*)
FROM employees
GROUP BY 1, 2;
SELECT bez FROM – koniec z DUAL
Drobiazg, który cieszy. Proste wyliczenia i wywołania funkcji bez sztucznego FROM dual:
SELECT 25.50 * 25.25; -- 643.875
SELECT SYSDATE; -- bieżąca data
SELECT 'Witaj ' || USER; -- bez FROM dual
Wstawianie wielu wierszy jednym VALUES
Tzw. Table Value Constructor. Zamiast wielu osobnych INSERT albo INSERT ALL – jedna lista wartości. Działa też w SELECT:
INSERT INTO slownik_statusow (kod, opis) VALUES
('NEW', 'Nowy'),
('PRC', 'W realizacji'),
('FIN', 'Zakończony'),
('ERR', 'Błąd');
-- VALUES jako źródło wierszy w SELECT:
SELECT * FROM (VALUES (1,'a'), (2,'b'), (3,'c')) AS t(nr, litera);
Złączenia bezpośrednie w UPDATE i DELETE
23ai pozwala użyć FROM z innymi tabelami wprost w UPDATE i DELETE, bez korelowanych podzapytań:
-- Podwyżka dla działu IT - złączenie wprost w UPDATE
UPDATE employees e
SET e.salary = e.salary * 1.10
FROM departments d
WHERE e.department_id = d.department_id
AND d.department_name = 'IT';
-- DELETE ze złączeniem
DELETE FROM order_items oi
FROM orders o
WHERE oi.order_id = o.order_id
AND o.status = 'CANCELLED';
RETURNING ze starą i nową wartością
Klauzula RETURNING w 23ai potrafi zwrócić jednocześnie wartość przed i po zmianie – idealne do audytu i logów bez dodatkowego SELECT:
DECLARE
v_old NUMBER;
v_new NUMBER;
BEGIN
UPDATE employees
SET salary = salary * 1.10
WHERE employee_id = 100
RETURNING OLD salary, NEW salary INTO v_old, v_new;
DBMS_OUTPUT.PUT_LINE('Przed: '||v_old||' Po: '||v_new);
END;
/
SQL Domains – wielokrotnie używalne reguły kolumn
Domena to nazwany zestaw typu + ograniczeń + formatowania, który przypisujesz wielu kolumnom. Definiujesz regułę (np. poprawny e-mail) raz, a używasz wszędzie:
CREATE DOMAIN email_dom AS VARCHAR2(255)
CONSTRAINT email_chk CHECK (REGEXP_LIKE(email_dom, '^[^@]+@[^@]+\.[^@]+$'));
CREATE TABLE kontakty (
id NUMBER,
email VARCHAR2(255) DOMAIN email_dom -- reguła dziedziczona z domeny
);
Adnotacje (Annotations) – metadane wprost w schemacie
Lekka alternatywa dla komentarzy – pary nazwa/wartość opisujące kolumny i tabele, czytelne dla narzędzi i aplikacji (np. "to pole jest wrażliwe", "ukryj w UI"):
CREATE TABLE pacjenci (
id NUMBER,
pesel VARCHAR2(11) ANNOTATIONS (PII, Display 'Numer PESEL'),
imie VARCHAR2(50) ANNOTATIONS (Display 'Imię')
) ANNOTATIONS (Schemat 'medyczny');
SELECT * FROM user_annotations_usage; -- przegląd adnotacji
JSON Relational Duality Views – jeden model, dwa widoki
Sztandarowa funkcja 23ai. Te same dane relacyjne możesz czytać i zapisywać jako dokumenty JSON – baza synchronizuje oba światy. Aplikacja webowa dostaje wygodny JSON, a integralność i transakcyjność pilnuje relacyjny silnik:
CREATE JSON RELATIONAL DUALITY VIEW dzial_dv AS
SELECT JSON {
'_id' : d.department_id,
'nazwa' : d.department_name,
'pracownicy' :
[ SELECT JSON { 'id': e.employee_id, 'nazwisko': e.last_name }
FROM employees e WITH INSERT UPDATE
WHERE e.department_id = d.department_id ]
}
FROM departments d WITH INSERT UPDATE DELETE;
-- Czytasz jako dokument:
SELECT data FROM dzial_dv WHERE json_value(data, '$._id') = 50;
-- ...i zapisujesz jako dokument - baza rozkłada to na tabele:
-- (INSERT/UPDATE na widoku dualnym)
JSON Schema – walidacja struktury dokumentów
23ai pozwala wymusić zgodność dokumentu JSON ze schematem wprost w CHECK:
CREATE TABLE produkty (
id NUMBER,
dane JSON VALIDATE '{
"type": "object",
"properties": {
"sku": {"type": "string"},
"cena": {"type": "number", "minimum": 0}
},
"required": ["sku", "cena"]
}'
);
-- INSERT niezgodny ze schematem zostanie odrzucony
Typ VECTOR i AI Vector Search – sedno "ai" w 23ai
Najważniejsza nowość całej wersji. Natywny typ VECTOR przechowuje embeddingi (wektory cech) obok danych biznesowych, a funkcja VECTOR_DISTANCE liczy podobieństwo semantyczne. Dzięki temu wyszukiwanie "po znaczeniu" (RAG, rekomendacje, semantic search) robisz zwykłym SQL-em – bez osobnej bazy wektorowej:
CREATE TABLE dokumenty (
id NUMBER,
tytul VARCHAR2(200),
tresc CLOB,
embedding VECTOR(768, FLOAT32) -- 768 wymiarów, liczby 32-bit
);
-- Wyszukiwanie semantyczne: 5 dokumentów najbliższych zapytaniu
SELECT id, tytul
FROM dokumenty
ORDER BY VECTOR_DISTANCE(embedding, :wektor_pytania, COSINE)
FETCH FIRST 5 ROWS ONLY;
-- Indeks wektorowy HNSW dla szybkiego wyszukiwania przybliżonego
CREATE VECTOR INDEX idx_emb ON dokumenty(embedding)
ORGANIZATION INMEMORY NEIGHBOR GRAPH
DISTANCE COSINE;
Dlaczego to ważne: wektor + relacja w jednej bazie oznacza, że filtr biznesowy (WHERE status='AKTYWNY') i wyszukiwanie semantyczne dzieją się w jednym zapytaniu, w jednej transakcji. To właśnie ta funkcja dała wersji literę "ai" w nazwie.
To nie tylko wektory. Drugą twarzą AI w 23ai jest Select AI – odpytujesz bazę po ludzku, a ona sama pisze SQL. Wystarczy SELECT AI 'przychód w podziale na miesiące', by dostać gotowe zapytanie i wynik – bez znajomości schematu i składni. Wyszukiwanie wektorowe, Select AI oraz uczenie maszynowe w samej bazie rozkładamy na czynniki pierwsze, na realnych danych i zrzutach z żywej bazy, w osobnym artykule: AI w bazie Oracle – Vector Search, Select AI i Machine Learning. Zobaczysz tam m.in. realne SELECT AI nad danymi sprzedażowymi i to, jak baza sama zwraca gotowy SQL. Jeśli temat AI w 23ai Cię wciągnął – to naturalny następny krok.
Ściągawka: co w której wersji
| Wersja | Kluczowe nowości |
|---|---|
| 19c | LISTAGG DISTINCT, Automatic Indexing, Real-Time Statistics, SQL Quarantine, Active Data Guard DML Redirect |
| 21c | Natywny typ JSON, SQL Macros (SCALAR/TABLE), JavaScript w bazie (DBMS_MLE), Blockchain & Immutable Tables, Automatic In-Memory |
| 23ai | BOOLEAN, IF [NOT] EXISTS, GROUP BY po aliasie, SELECT bez FROM, multi-row VALUES, JOIN w UPDATE/DELETE, RETURNING OLD/NEW, SQL Domains, Annotations, JSON Duality Views, JSON Schema, typ VECTOR + AI Vector Search |
Jak zacząć korzystać z nowości
- Najszybsza droga do zabawy z 23ai to Oracle Database 23ai Free – darmowa edycja do nauki i developmentu (kontener Docker albo instalka na VM). Większość składni z tego artykułu uruchomisz w 5 minut.
- Na produkcji sprawdź poziom edycji i licencji – część funkcji (Automatic Indexing, Real-Time Statistics, In-Memory) wymaga Enterprise Edition lub konkretnych opcji.
- Przy migracji z 12c/18c zaplanuj test planów wykonania – nowy optymalizator i automatyczne statystyki potrafią zmienić plany; warto porównać wydajność przed przełączeniem.
- Nowości składni 23ai (BOOLEAN, GROUP BY po aliasie, IF EXISTS) ułatwiają przenoś ność kodu z PostgreSQL/MySQL – dobry moment, by ujednolicić standardy w zespole.
Nowe wersje Oracle to nie kosmetyka – to realne narzędzia, które skracają kod, podnoszą wydajność i otwierają bazie drogę do zastosowań AI. Jeśli chcesz przećwiczyć je na prawdziwych przykładach – od zaawansowanego SQL, przez tuning wydajności, po programowanie w PL/SQL – zajrzyj na szkolenia Oracle JSystems.
Szkolenie kompleksowe: Tuning wydajności SQL w Oracle
Zaawansowany SQL w Oracle
Funkcje analityczne i okienkowe, zapytania hierarchiczne, pivot/unpivot, wyrażenia regularne i optymalizacja złożonych zapytań – pełne wyciskanie możliwości SQL-a w Oracle.
Szkolenie PL/SQL - Zaawansowany SQL i programowanie w PL/SQL
5 dni intensywnych warsztatów z Moniką Lewandowską - jedną z najbardziej doświadczonych ekspertek Oracle w Polsce (Oracle ACE Pro). Dynamiczny SQL, kolekcje, kursory, optymalizacja, utPLSQL. Terminy gwarantowane, ocena 4.9/5.
5 dni
To szkolenie może być dofinansowane dla Ciebie z KFS lub BUR.
★★★★★Średnia ocena naszych szkoleń w Google: 5/5














