What's the equivalent to Oracle Packages in PostgreSQL
I’m pretty new to PostgreSQL and I wonder if such a thing exists.
I saw some discussions, but nothing concrete..
3 Answers 3
No, there is no equivalent.
The only remotely similar thing would be to create one schema for each «package» and put all functions of one package into that schema. That way you have at least something like the namespace that packages give you.
This of course does not give you package private functions or package wide variables at all.
Postgresql пакеты как в oracle
This section explains differences between PostgreSQL ‘s PL/pgSQL language and Oracle’s PL/SQL language, to help developers who port applications from Oracle ® to PostgreSQL .
PL/pgSQL is similar to PL/SQL in many aspects. It is a block-structured, imperative language, and all variables have to be declared. Assignments, loops, and conditionals are similar. The main differences you should keep in mind when porting from PL/SQL to PL/pgSQL are:
If a name used in an SQL command could be either a column name of a table used in the command or a reference to a variable of the function, PL/SQL treats it as a column name. By default, PL/pgSQL will throw an error complaining that the name is ambiguous. You can specify plpgsql.variable_conflict = use_column to change this behavior to match PL/SQL , as explained in Section 43.11.1. It’s often best to avoid such ambiguities in the first place, but if you have to port a large amount of code that depends on this behavior, setting variable_conflict may be the best solution.
In PostgreSQL the function body must be written as a string literal. Therefore you need to use dollar quoting or escape single quotes in the function body. (See Section 43.12.1.)
Data type names often need translation. For example, in Oracle string values are commonly declared as being of type varchar2 , which is a non-SQL-standard type. In PostgreSQL , use type varchar or text instead. Similarly, replace type number with numeric , or use some other numeric data type if there’s a more appropriate one.
Instead of packages, use schemas to organize your functions into groups.
Since there are no packages, there are no package-level variables either. This is somewhat annoying. You can keep per-session state in temporary tables instead.
Integer FOR loops with REVERSE work differently: PL/SQL counts down from the second number to the first, while PL/pgSQL counts down from the first number to the second, requiring the loop bounds to be swapped when porting. This incompatibility is unfortunate but is unlikely to be changed. (See Section 43.6.5.5.)
FOR loops over queries (other than cursors) also work differently: the target variable(s) must have been declared, whereas PL/SQL always declares them implicitly. An advantage of this is that the variable values are still accessible after the loop exits.
There are various notational differences for the use of cursor variables.
Postgresql пакеты как в oracle
Подскажите пожалуйтса, есть ли возможность создать пакеты или какой либо аналог как в oracle?
- Войдите или зарегистрируйтесь, чтобы добавлять комментарии
Быть администратором
Быть администратором PostgreSQL не означает автоматически быть таковым в Oracle и вообще знание последнего.
Поэтому рассказывайте в подробностях, что такое пакет и с чем его едят
- Войдите или зарегистрируйтесь, чтобы добавлять комментарии
Аналогов PL/SQL пакета в
Аналогов PL/SQL пакета в PostgreSQL нет.
Документация рекомендует для группировки функций использовать отдельные схемы.
Вместо пакетных переменных можно использовать временные таблицы.
Postgresql пакеты как в oracle
В Postgres Pro реализованы пакеты, подобные пакетам в Oracle . Они могут быть полезны при портировании с PL/SQL на PL/pgSQL . В этом разделе описаны различия между пакетами в Postgres Pro и Oracle.
В Oracle пакет — это объект, представляющий собой схему, которая группирует логически связанные типы, глобальные переменные и подпрограммы (процедуры и функции). Пакет состоит из спецификации и тела (хотя, в общем случае тело пакета может отсутствовать). В спецификации пакета объявляются элементы, на которые можно ссылаться вне пакета и использовать в приложениях: типы, переменные, константы, исключения, курсоры и подпрограммы. Тело пакета включает в себя реализацию подпрограмм пакета, объявление внутренних переменных, а также секцию инициализации. Переменные, типы и подпрограммы, объявленные в теле пакета, недоступны вне пакета.
Ниже приведён пример спецификации пакета counter на PL/SQL в Oracle , содержащего глобальную переменную n и функцию inc :
В теле пакета counter в Oracle объявлены функция inc и глобальная переменная k (доступна только в теле пакета).
Глобальные переменные пакета существуют в течение сеанса. Обратите внимание, что в теле пакета была определена секция инициализации — блок кода, который выполняется один раз за сеанс при первом обращении к любому элементу пакета. В Oracle к элементам пакета можно обращаться, используя запись с точкой: имя_пакета . элемент_пакета .
В Postgres Pro пакет по сути представляет собой схему, содержащую функцию инициализации и не содержащую ничего, кроме функций, процедур и составных типов. Функция инициализации — это функция на PL/pgSQL с именем __init__ , которая не имеет аргументов и возвращает значение типа void . Функция инициализации должна быть определена до любой другой функции пакета. Все переменные, объявленные в функции инициализации, являются глобальными и публичными, то есть функции других пакетов могут обращаться к ним, используя запись с точкой. Например, на переменную bar , объявленную в функции __init__ пакета foo , можно ссылаться как foo.bar .
Переменные пакета доступны только из кода на языке PL/pgSQL . Для получения значений глобальных переменных пакета из SQL-запроса ( SELECT ) или DML-оператора ( INSERT , UPDATE , DELETE ), необходимо создать функцию-геттер, возвращающую значение глобальной переменной. Для определения переменных пакета, объявленных как константы, используется стандартный для PL/pgSQL синтаксис. Функция инициализации пакета вызывается автоматически при первом обращении к любому из следующих элементов в текущем сеансе:
- Любая функция данного пакета с модификатором #package
- Блок кода (анонимный или функция), импортирующий данный пакет
Функцию инициализации можно вызвать вручную, чтобы сбросить значения переменных пакета. Для этого также можно использовать встроенную функцию plpgsql_reset_packages() , но она сбрасывает значения глобальных переменных всех пакетов в текущем сеансе (аналог DBMS_SESSION.RESET_PACKAGES в Oracle ).
Описанный выше пример пакета counter в Oracle после портирования в Postgres Pro примет следующий вид:
Использовать этот пакет в Postgres Pro можно так:
Стоит отметить следующее.
Пакет не может содержаться в схеме, так как сам является схемой.
Имя пакета должно отличаться от имени любого уже существующего пакета или схемы в текущей базе данных.
Пакет может содержать только составные типы, глобальные переменные, процедуры и функции (например, создание таблиц, представлений, последовательностей в пакетах не поддерживается).
Все функции и переменные пакета являются публичными. Все переменные пакета доступны из любого блока кода, импортирующего пакет. Спецификация пакета и тело пакета не определяются отдельно.
Как функции пакета, так и импортирующие его блоки кода должны быть написаны на языке PL/pgSQL .
Обращение извне ко всем элементам пакета должно происходить через квалифицированные имена, то есть с указанием имени пакета. Внутри пакета функции могут обращаться к элементам напрямую.
Глобальные переменные пакета могут инициализироваться как при объявлении:
так и позже в теле функции инициализации __init__ . Для внешнего кода, использующего пакет, эти варианты эквивалентны.
Типы должны быть объявлены в начале пакета, до определения первой подпрограммы.
Для поддержки пакетов Postgres Pro включает следующие усовершенствования: