Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Dlaczego wybór z procedury składowanej nie jest obsługiwany w relacyjnych bazach danych?

TL;DR :możesz wybierz z funkcji (wartościami z tabeli) lub z dowolnej funkcji w PostgreSQL. Ale nie z procedur składowanych.

Oto „intuicyjne”, nieco niezależne od bazy danych wyjaśnienie, ponieważ uważam, że SQL i jego liczne dialekty są zbyt organicznie rozwiniętym językiem/koncepcją, aby można było to wyjaśnić jako fundamentalne, „naukowe”.

Procedury a funkcje, historycznie

Naprawdę nie widzę sensu wybierania spośród procedur składowanych, ale jestem uprzedzony przez lata doświadczenia i akceptuję status quo, i na pewno widzę, jak rozróżnia się procedury i funkcje może być mylące i jak chciałbyś, aby były bardziej wszechstronne i potężne. W szczególności w SQL Server, Sybase lub MySQL procedury mogą zwracać dowolną liczbę zestawów wyników/liczby aktualizacji, chociaż nie jest to to samo, co funkcja zwracająca dobrze zdefiniowany typ.

Pomyśl o procedurach jako koniecznych rutynach (ze skutkami ubocznymi) i działa jako czyste procedury bez skutków ubocznych. SELECT samo stwierdzenie jest również "czysty" bez efektów ubocznych (oprócz potencjalnych efektów blokowania), więc sensowne jest myślenie o funkcjach jako o jedynym typie podprogramów, które mogą być użyte w SELECT oświadczenie.

W rzeczywistości pomyśl o funkcjach jako o procedurach z silnymi ograniczeniami zachowania, podczas gdy procedury mogą wykonywać dowolne programy.

Języki 4GL kontra 3GL

Innym sposobem spojrzenia na to jest perspektywa SQL jako język programowania czwartej generacji (4GL) . 4GL może działać rozsądnie tylko wtedy, gdy jest mocno ograniczony w swoich możliwościach. Wspólne wyrażenia tabelowe uzupełnione o turystykę SQL , tak, ale deklaratywny charakter SQL nadal uniemożliwia jego bycie językiem ogólnego przeznaczenia z praktycznej, codziennej perspektywy.

Procedury składowane są sposobem na obejście tego ograniczenia. Czasami chcesz być kompletnym i praktyczny. Tak więc procedury składowane odwołują się do imperatywu, mają skutki uboczne, są transakcyjne itp.

Przechowywane funkcje to sprytny sposób na wprowadzenie niektórych Funkcje 3GL/języka proceduralnego do czystszego świata 4GL za cenę zakazywania efektów ubocznych wewnątrz nich (chyba że chcesz otworzyć puszkę pandory i mieć całkowicie nieprzewidywalne SELECT oświadczenia).

Fakt, że niektóre bazy danych umożliwiają ich procedurom składowanym zwracanie dowolnej liczby zestawów wyników/kursorów, jest cechą dopuszczania przez nie dowolnych zachowań, w tym skutków ubocznych. W zasadzie nic, co powiedziałem, nie zapobiegłoby temu szczególnemu zachowaniu również w przechowywanych funkcjach, ale byłoby to bardzo niepraktyczne i trudne w zarządzaniu, gdyby pozwolono im to zrobić w kontekście SQL, języka 4GL.

Tak więc:

  • Procedury mogą wywoływać procedury, dowolną funkcję i SQL
  • „Czyste” funkcje mogą wywoływać „czyste” funkcje i SQL
  • SQL może wywoływać „czyste” funkcje i SQL

Ale:

  • „Czyste” funkcje wywołujące procedury stają się „nieczystymi” funkcjami (jak procedury)

Oraz:

  • SQL nie może wywoływać procedur
  • SQL nie może wywoływać „nieczystych” funkcji

Przykłady „czystych” funkcji z wartościami tabelarycznymi:

Oto kilka przykładów użycia „czystych” funkcji o wartościach tabelarycznych:

Wyrocznia

CREATE TYPE numbers AS TABLE OF number(10);
/

CREATE OR REPLACE FUNCTION my_function (a number, b number)
RETURN numbers
IS
BEGIN
    return numbers(a, b);
END my_function;
/

A potem:

SELECT * FROM TABLE (my_function(1, 2))

Serwer SQL

CREATE FUNCTION my_function(@v1 INTEGER, @v2 INTEGER)
RETURNS @out_table TABLE (
    column_value INTEGER
)
AS
BEGIN
    INSERT @out_table
    VALUES (@v1), (@v2)
    RETURN
END

A potem

SELECT * FROM my_function(1, 2)

PostgreSQL

Pozwól, że powiem coś na temat PostgreSQL.

PostgreSQL jest niesamowity i dlatego stanowi wyjątek. Jest to również dziwne i prawdopodobnie 50% jego funkcji nie powinno być wykorzystywane w produkcji. Obsługuje tylko „funkcje”, a nie „procedury”, ale te funkcje mogą działać jak cokolwiek. Sprawdź następujące:

CREATE OR REPLACE FUNCTION wow ()
RETURNS SETOF INT
AS $$
BEGIN
    CREATE TABLE boom (i INT);

    RETURN QUERY
    INSERT INTO boom VALUES (1)
    RETURNING *;
END;
$$ LANGUAGE plpgsql;

Skutki uboczne:

  • Utworzono tabelę
  • Wstawiono rekord

Jednak:

SELECT * FROM wow();

Plony

wow
---
1


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. znak do tej pory w Oracle sql

  2. Zmień tytuł strony na podstawie pozycji w Oracle APEX 4.0

  3. Jak używać funkcji NVL() w Oracle

  4. Wyszukiwanie bez rozróżniania wielkości liter w Oracle

  5. Jak uruchomić SQL w skrypcie powłoki