|
Разширяване функционалността на PostgreSQL: Програмиране на функции с PERL
Въведение. Функции. Процедурни езици (PLs) в PostgreSQL: Възможността за разширяване на PostgreSQL се дължи на факта, че тази система за управление на бази данни (от тук нататък ще се използва DBMS – DataBase Management System) се управлява от каталог. Каталозите се показват на потребителя във вид на таблица, но всъщност те са местата, където DBMS съхранява вътрешната си информация. Разликата между PostgreSQLи стандартнте релационни DBMS е, че PostgreSQL съхранява в каталозите си не само информация за базите данни, таблиците и колоните, а също така и за типовете данни, функциите, методите за достъп и т.н. Каталозите могат да бъдат променяни от потребителя и в този смисъл PostgreSQL може да бъде разширявана динамично от потребителя, докато при конвенционалните DBMS единствените начини за разширяване на функционалността са чрез добавяне на функции в сорс кода или, чрез зареждане на модули, написани специално от производителя на системата. В PostgreSQL потребителят може да задава нови функции и типове в процеса на работа без да се налага да спира, рестартира или прекомпилира DBMS. Функциите в PostgreSQL се характеризират със свойство волатилност (volatility), което може да приема стойности VOLATILE, STABLE или IMMUTABLE. По подразбиране, когато не е указано друго, функциите са VOLATILE. Когато една функция е VOLATILE, тя може да променя базите данни, да връща различен резултат при всяко извикване със същите аргументи. STABLE функциите не могат да променят базата данни и са „задължени“ да връщат един и същ резултат при едни и същи аргументи в рамките на заявката в която са използвани. И накрая IMMUTABLE функциите – те не могат да променят базата данни и връщат еднакъв резултат при всяко извикване със същите аргументи. Например функцията, която стои зад оператора за събиране на цели числа + е IMMUTABLE, защото когато и да извикаме 3+4 ще получим 7. В PostgreSQL могат да бъдат дефинирани повече от 1 функции, използващи същото име, стига аргументите, които взимат да са от различен тип. Това се начира „презареждане“ на функциите. При изпълнение на заявка с презаредени функции, сървърът определя коя точно функция е извикана според типа на аргументите. От това следва, че особено трябва да се внимава за „препокриващи се“ типове. Например при дефинирани функции: CODE
не е очевидно коя от двете функции ще бъде извикана при fnc(5). Както току що видяхте функциите се създават с конструкцията CREATE FUNCTION. Последната разполага с не малко на брой опции и затова тук ще се спрем на една най-обща форма, която ще използваме в урока: CODE
Пример: CODE
Аргументите към PERL функцията се намират в масива @_ и могат да бъдат извлечени, чрез $_[0], $_[1], $_[2], $_[3] ... $_[n] или чрез конструкция от сорта на my ($arg1, $arg2, $arg3) = @_; За пример ще използваме функция, която да ни връща произведението върху сбора на две числа: CODE
На първите два реда от функцията проверяваме дали някоя от въведените стойности не е NULL или пък и двата аргумента не са 0 (нула) и ако е така връщаме undef, което се интерпретира от PostgreSQL като NULL. Добре е винаги да правим такава проверка, защото PERL възприема NULL като 0 (нула), а това може да доведе до големи главоболия – най-малкото заявката Ви може да пропадне, заради деление на 0. PERL функциите могат да приемат и сложни типове данни. Последните се предават като хешове. Нека се върнем на примера с ж.п гарата от урока „Views, Foreign Keys, Транзакции и Унаследяване“. Там имахме таблицата „служители“, която бяхме дефинирали така: CODE
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||









