Oracle
 sql >> база данни >  >> RDS >> Oracle

Защо изборът от съхранена процедура не се поддържа в релационни бази данни?

TL;DR :вие можете изберете от (таблични) функции или от всякакъв вид функция в PostgreSQL. Но не и от съхранени процедури.

Ето едно „интуитивно“, донякъде агностично на базата данни обяснение, тъй като вярвам, че SQL и неговите многобройни диалекти са твърде много органично развит език/концепция, за да има фундаментално, „научно“ обяснение за това.

Процедури срещу функции, исторически

Всъщност не виждам смисъл да избирам от съхранени процедури, но съм предубеден от години опит и приемане на статуквото и със сигурност виждам каква е разликата между процедурите и функции могат да бъдат объркващи и как човек би искал те да бъдат по-гъвкави и мощни. По-конкретно в SQL Server, Sybase или MySQL, процедурите могат да върнат произволен брой набори от резултати / брой актуализации, въпреки че това не е същото като функция, която връща добре дефиниран тип.

Мислете за процедурите като за наложителни процедури (със странични ефекти) и на функции като чисти рутинни процедури без странични ефекти. A SELECT самото изявление също е "чисто" без странични ефекти (освен потенциалните ефекти на заключване), така че има смисъл да мислим за функциите като за единствените типове рутинни процедури, които могат да се използват в SELECT изявление.

Всъщност, мислете за функциите като за рутинни процедури със силни ограничения върху поведението, докато на процедурите е разрешено да изпълняват произволни програми.

4GL срещу 3GL езици

Друг начин да погледнете това е от гледна точка на това, че SQL е език за програмиране от 4-то поколение (4GL) . 4GL може да работи разумно само ако е силно ограничен в това, което може да прави. Общи таблични изрази направиха SQL turing-complete , да, но декларативният характер на SQL все още му пречи да бъде език с общо предназначение от практическа, ежедневна гледна точка.

Съхранените процедури са начин за заобикаляне на това ограничение. Понякога искате за да бъде завършен и практичен. И така, съхранените процедури прибягват до това да бъдат императивни, да имат странични ефекти, да са транзакционни и т.н.

Съхранените функции са умен начин за въвеждане на някои Функциите на 3GL / процедурния език в по-чистия свят на 4GL на цената на забраната на страничните ефекти вътре в тях (освен ако не искате да отворите кутията на Пандора и да имате напълно непредсказуем SELECT изявления).

Фактът, че някои бази данни позволяват на техните съхранени процедури да връщат произволен брой набори от резултати / курсори, е характеристика на тяхното разрешаване на произволно поведение, включително странични ефекти. По принцип нищо от казаното от мен не би предотвратило това конкретно поведение и в съхранените функции, но би било много непрактично и трудно за управление, ако им беше позволено да го правят в контекста на SQL, езика 4GL.

Така:

  • Процедурите могат да извикват процедури, всяка функция и SQL
  • "Чистите" функции могат да извикват "чисти" функции и SQL
  • SQL може да извиква „чисти“ функции и SQL

Но:

  • „Чистите“ функции, извикващи процедури, стават „нечисти“ функции (като процедури)

И:

  • SQL не може да извиква процедури
  • SQL не може да извиква "нечисти" функции

Примери за „чисти“ функции с таблични стойности:

Ето няколко примера за използване на „чисти“ функции с таблични стойности:

Оракул

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;
/

И след това:

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

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

И след това

SELECT * FROM my_function(1, 2)

PostgreSQL

Позволете ми да кажа нещо за PostgreSQL.

PostgreSQL е страхотен и следователно е изключение. Освен това е странен и вероятно 50% от функциите му не трябва да се използват в производството. Той поддържа само „функции“, не „процедури“, но тези функции могат да действат като всичко. Вижте следното:

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;

Странични ефекти:

  • Създава се таблица
  • Вмъква се запис

И все пак:

SELECT * FROM wow();

Добив

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. Oracle база данни TNS Дължината на стойността за ключ „източник на данни“ надвишава ограничението си от „128“

  2. LINQ Използвайте като вместо (( NVL(INSTR(x, y), 0) ) =1)

  3. Получаване на неизползвани уникални стойности в SQL таблица

  4. Как да премахна дубликати от listagg

  5. Агентът е блокиран