<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL</id>
	<title>PL/SQL - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL"/>
	<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=PL/SQL&amp;action=history"/>
	<updated>2026-07-16T12:12:46Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://camokathomelab.servebeer.com/mediawiki/index.php?title=PL/SQL&amp;diff=51638&amp;oldid=prev</id>
		<title>imported&gt;Lê Lợi (bot): Автодевикификация Шаблон:Языки программирования.</title>
		<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=PL/SQL&amp;diff=51638&amp;oldid=prev"/>
		<updated>2025-12-03T11:41:25Z</updated>

		<summary type="html">&lt;p&gt;Автодевикификация &lt;a href=&quot;/mediawiki/index.php?title=%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%AF%D0%B7%D1%8B%D0%BA%D0%B8_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Шаблон:Языки программирования (страница не существует)&quot;&gt;Шаблон:Языки программирования&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Карточка языка программирования&lt;br /&gt;
  |name = PL/SQL&lt;br /&gt;
  |logo = &lt;br /&gt;
  |semantics = [[императивное программирование|императивное]], [[объектно-ориентированное программирование|объектно-ориентированное]] программирование&lt;br /&gt;
  |class = [[Процедурный язык программирования|процедурный]]&lt;br /&gt;
  |year = [[1992]]&lt;br /&gt;
  |designer = &lt;br /&gt;
  |typing = [[Строгая типизация|строгая]], [[Статическая типизация|статическая]] &lt;br /&gt;
  |implementations = &lt;br /&gt;
  |dialects =&lt;br /&gt;
  |influenced_by = [[Ада (язык программирования)|Ada]]&lt;br /&gt;
  |influenced = [[PL/pgSQL]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PL/SQL&amp;#039;&amp;#039;&amp;#039; (&amp;#039;&amp;#039;&amp;#039;P&amp;#039;&amp;#039;&amp;#039;rocedural &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;anguage &amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;tructured &amp;#039;&amp;#039;&amp;#039;Q&amp;#039;&amp;#039;&amp;#039;uery &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;anguage) — [[язык программирования]], [[Процедурное программирование|процедурное]] расширение языка [[SQL]], разработанное корпорацией [[Oracle Corporation|Oracle]]. Базируется на языке [[Ада (язык программирования)|Ада]]&amp;lt;ref&amp;gt;{{книга&lt;br /&gt;
 |автор         = McDonald, Connor&lt;br /&gt;
 |часть         = &lt;br /&gt;
 |заглавие      = Mastering Oracle PL/SQL: practical solutions&lt;br /&gt;
 |оригинал      = &lt;br /&gt;
 |ссылка        = https://books.google.com/books?id=E4yq9orqFTAC&amp;amp;pg=PA59&amp;amp;dq=Oracle+PL/SQL+ADA&amp;amp;hl=en&amp;amp;ei=RyVkTbCGGoSW8QPHv9XxCA&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=9&amp;amp;ved=0CGIQ6AEwCA#v=onepage&amp;amp;q=Oracle%20PL%2FSQL%20ADA&amp;amp;f=false&lt;br /&gt;
 |ответственный = &lt;br /&gt;
 |издание       = &lt;br /&gt;
 |место         = &lt;br /&gt;
 |издательство  = [[Springer Science+Business Media|Springer]]&lt;br /&gt;
 |год           = 2004&lt;br /&gt;
 |volume        = &lt;br /&gt;
 |pages         = &lt;br /&gt;
 |allpages      = 605&lt;br /&gt;
 |серия         = &lt;br /&gt;
 |isbn          = 978-1590592175&lt;br /&gt;
 |тираж         = &lt;br /&gt;
 |archive-date   = 2014-04-26&lt;br /&gt;
 |archive-url    = https://web.archive.org/web/20140426155027/http://books.google.com/books?id=E4yq9orqFTAC&amp;amp;pg=PA59&amp;amp;dq=Oracle+PL/SQL+ADA&amp;amp;hl=en&amp;amp;ei=RyVkTbCGGoSW8QPHv9XxCA&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=9&amp;amp;ved=0CGIQ6AEwCA#v=onepage&amp;amp;q=Oracle%20PL%2FSQL%20ADA&amp;amp;f=false&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;. &amp;lt;!-- А не Модула??? Точно Ada, см. на EXCEPTION-WHEN, PRAGMA, и на источники, которых можно привести много --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PL/SQL встроен в следующие [[СУБД]]: [[Oracle Database]] (начиная с версии 7), {{Не переведено|TimesTen||en|TimesTen}} (с версии 11.2.1) и [[IBM DB2]] (с версии 9.7)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
 |url         = http://www.ibm.com/developerworks/data/library/techarticle/dm-0907oracleappsondb2/index.html&lt;br /&gt;
 |title       = DB2 9.7: Run Oracle applications on DB2 9.7 for Linux, Unix, and Windows&lt;br /&gt;
 |first       = Serge&lt;br /&gt;
 |last        = Rielau&lt;br /&gt;
 |date        = 2010-05-26&lt;br /&gt;
 |work        = Developer Works&lt;br /&gt;
 |publisher   = [[IBM]]&lt;br /&gt;
 |access-date  = 2011-02-21&lt;br /&gt;
 |lang        = en&lt;br /&gt;
 |archive-url  = https://www.webcitation.org/61CqX2haI?url=http://www.ibm.com/developerworks/data/library/techarticle/dm-0907oracleappsondb2/index.html&lt;br /&gt;
 |archive-date = 2011-08-25&lt;br /&gt;
 |url-status     = dead&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;. Также PL/SQL используется как встроенный язык для [[RAD (программирование)|средства быстрой разработки]] [[Oracle Forms]], инструмента разработки отчётов [[Oracle Reports]] и в [[Oracle Application Express]].&lt;br /&gt;
&lt;br /&gt;
== Функциональность ==&lt;br /&gt;
PL/SQL даёт возможность использовать [[Переменная (программирование)|переменные]], [[Оператор (программирование)|операторы]], [[Массив (программирование)|массивы]], [[Курсор (базы данных)|курсоры]] и [[Обработка исключений|исключения]]. Начиная с версии 8 доступна и [[Объектно-ориентированное программирование|объектно-ориентированная]] модель.&lt;br /&gt;
&lt;br /&gt;
Стандартный SQL является специализированным [[Декларативный язык программирования|декларативным языком программирования]]. На язык наложены определённые ограничения, такие как, например, отсутствие прямой поддержки циклов. PL/SQL же, как [[Полнота по Тьюрингу|полный по Тьюрингу]] язык, позволяет разработчикам обрабатывать данные в [[Реляционные базы данных|реляционной базе]], используя [[Императивное программирование|императивный стиль программирования]]. Операторы SQL могут быть легко вызваны непосредственно из PL/SQL-процедуры, функции или [[Триггер (базы данных)|триггера]] (иногда с некоторыми ограничениями).&lt;br /&gt;
&lt;br /&gt;
== Базовая структура кода ==&lt;br /&gt;
Программа на PL/SQL состоит из [[блок (программирование)|блоков]] (анонимных или поименованных). Блок может содержать вложенные блоки, называемые иногда подблоками. Общая форма PL/SQL-блока:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;DECLARE&lt;br /&gt;
-- Описания блока, переменные, типы, курсоры и т. п. (опционально)&lt;br /&gt;
BEGIN&lt;br /&gt;
-- Непосредственно код программы&lt;br /&gt;
EXCEPTION&lt;br /&gt;
-- Обработка исключений (опционально)&lt;br /&gt;
END;&lt;br /&gt;
/* Многострочные&lt;br /&gt;
комментарии… */&lt;br /&gt;
-- Однострочный комментарий&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;!-- {|&lt;br /&gt;
|&amp;lt;font style=&amp;quot;color:#0000FF&amp;quot;&amp;gt;DECLARE&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;-- Описания блока, переменные, типы, курсоры и т. п. (опционально)&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;font style=&amp;quot;color:#0000FF&amp;quot;&amp;gt;BEGIN&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;-- Непосредственно код программы&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;font style=&amp;quot;color:#0000FF&amp;quot;&amp;gt;EXCEPTION&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;-- Обработка исключений (опционально)&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;font style=&amp;quot;color:#0000FF&amp;quot;&amp;gt;END;&amp;lt;/font&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;/* Многострочные&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;комментарии… */&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;font style=&amp;quot;color:#006400&amp;quot;&amp;gt;--Однострочный комментарий&amp;lt;/font&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Язык PL/SQL позволяет определять следующие типы именованных блоков:&lt;br /&gt;
* процедуры;&lt;br /&gt;
* функции;&lt;br /&gt;
* объекты;&lt;br /&gt;
* пакеты.&lt;br /&gt;
&lt;br /&gt;
Все они могут быть [[Компиляция (программирование)|скомпилированы]] и сохранены как объекты базы данных в некоторой её схеме. Все именованные блоки кода, кроме пакетов, не хранят внутреннее состояние от вызова к вызову.&lt;br /&gt;
&lt;br /&gt;
Пакеты обеспечивают модульность для больших проектов, позволяя сгруппировать наборы именованных блоков кода, кроме того, в пакетах возможно хранение состояния на время жизни сессии базы данных, доступное для функций и процедур, входящих в пакет. Пакеты в PL/SQL содержат спецификацию и тело. Спецификация пакета может содержать определение констант, переменных, типов данных, объявление процедур и функций. Тело пакета определяет объявленные в спецификации процедуры и функции, а также может содержать блок кода инициализации пакета, определения внутренних констант, переменных, типов данных, процедур и функций. Все компоненты пакета, объявленные в его спецификации, могут быть доступны для использования извне пакета, в то время как тело пакета [[Инкапсуляция (программирование)|инкапсулирует]] реализацию этих компонентов, и извне недоступно. Тело и спецификация пакета могут модифицироваться, компилироваться и сохраняться независимо друг от друга.&lt;br /&gt;
&lt;br /&gt;
=== Типы данных ===&lt;br /&gt;
Язык PL/SQL поддерживает следующие категории типов:&lt;br /&gt;
* встроенные типы данных, включая коллекции и записи;&lt;br /&gt;
** скалярные;&lt;br /&gt;
** составные;&lt;br /&gt;
** ссылочные;&lt;br /&gt;
** [[LOB|LOB-типы]];&lt;br /&gt;
* объектные типы данных.&lt;br /&gt;
&lt;br /&gt;
=== Операторы управления ===&lt;br /&gt;
* операторы выбора:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
IF - THEN - END IF;&lt;br /&gt;
IF - THEN - ELSE - END IF;&lt;br /&gt;
IF - THEN - ELSIF - END IF;&lt;br /&gt;
IF - THEN - ELSIF - ELSE - END IF;&lt;br /&gt;
CASE - WHEN - THEN - END;&lt;br /&gt;
CASE - WHEN - THEN - ELSE - END;&amp;lt;/source&amp;gt;&lt;br /&gt;
* операторы цикла:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;LOOP - END LOOP;&lt;br /&gt;
WHILE - LOOP - END LOOP;&lt;br /&gt;
FOR - LOOP - END LOOP;&lt;br /&gt;
CONTINUE;&lt;br /&gt;
EXIT;&lt;br /&gt;
EXIT WHEN;&amp;lt;/source&amp;gt;&lt;br /&gt;
* операторы безусловного перехода:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;GOTO;&lt;br /&gt;
NULL;&lt;br /&gt;
&amp;lt;&amp;lt;labels&amp;gt;&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Пример программы ==&lt;br /&gt;
Программа, выводящая в консоли [[SQL*Plus]] строчку «[[Hello, World!]]» с использованием инициализированной переменной.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
set serveroutput on&lt;br /&gt;
&lt;br /&gt;
declare&lt;br /&gt;
    hello varchar2(50) := &amp;#039;Hello, world!&amp;#039;;&lt;br /&gt;
begin&lt;br /&gt;
    dbms_output.put_line(hello);&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
{{викиучебник|en:Oracle_Programming/SQL_Cheatsheet#PL.2FSQL}}&lt;br /&gt;
&lt;br /&gt;
== Работа с базой данных ==&lt;br /&gt;
&lt;br /&gt;
=== Статический SQL ===&lt;br /&gt;
В PL/SQL допускается включать готовые SQL-выражения непосредственно в код. В таком случае проверка выражения на корректность осуществляется уже при компиляции кода. Так, например, если используемая в запросе таблица не существует, то ошибка будет выдана уже на этапе [[Компилятор|компиляции]].&lt;br /&gt;
&lt;br /&gt;
==== Запрос одной строки из базы данных ====&lt;br /&gt;
Используется SQL-выражение &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, дополненное предложением &amp;lt;code&amp;gt;INTO&amp;lt;/code&amp;gt;, в котором указываются переменные, куда запишутся запрошенные данные. Количество и тип этих переменных должны соответствовать количеству (до версии Oracle 9 включительно переменных могло быть больше) и типу полей (хотя при определённых несоответствиях типов может произойти их неявное [[Приведение типов|приведение]]).&lt;br /&gt;
&lt;br /&gt;
В случае, если запрос вернул нулевое число строк, выбрасывается исключение &amp;lt;code&amp;gt;NO_DATA_FOUND&amp;lt;/code&amp;gt;. В случае, если строк больше, чем одна, выбрасывается исключение &amp;lt;code&amp;gt;TOO_MANY_ROWS&amp;lt;/code&amp;gt;. Эти исключения, вообще говоря, следует [[Обработка исключений|обрабатывать]] в соответствующей части блока за исключением случаев, когда предполагается, что они не могут быть выброшены. Например, при запросе данных из таблицы по их первичному ключу обработчик исключения &amp;lt;code&amp;gt;TOO_MANY_ROWS&amp;lt;/code&amp;gt; не нужен. Также в случае использования агрегированных функций, например MAX() или MIN() - исключение NO_DATA_FOUND не будет сгенерировано, а переменная получит в качестве результата NULL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
    empname   VARCHAR2(200);&lt;br /&gt;
BEGIN&lt;br /&gt;
    SELECT ename &lt;br /&gt;
        INTO empname        &lt;br /&gt;
        FROM scott.emp&lt;br /&gt;
        WHERE empno = 7439;&lt;br /&gt;
EXCEPTION&lt;br /&gt;
    WHEN NO_DATA_FOUND THEN&lt;br /&gt;
        DBMS_OUTPUT.put_line(&amp;#039;No records found!&amp;#039;);&lt;br /&gt;
    WHEN TOO_MANY_ROWS THEN&lt;br /&gt;
        DBMS_OUTPUT.put_line(&amp;#039;Found more than one string!&amp;#039;);&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Запрос нескольких строк из базы данных ====&lt;br /&gt;
Для последовательного считывания нескольких строк можно использовать [[Курсор (базы данных)|курсоры]] PL/SQL. Под курсором подразумевается указатель на очередную строку в результатах запроса. Открытие и закрытие курсора осуществляется операторами &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt;. Считывание значений, на которые указывает курсор, и его перевод на следующую строку осуществляется оператором &amp;lt;code&amp;gt;FETCH&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Считывание данных из запроса оформляется как [[Цикл (программирование)|цикл]]. Когда курсор дойдёт до конца результатов запроса, очередной вызов оператора &amp;lt;code&amp;gt;FETCH&amp;lt;/code&amp;gt; не считает новых данных, а атрибут &amp;lt;code&amp;gt;&amp;lt;имя_курсора&amp;gt;%NOTFOUND&amp;lt;/code&amp;gt; принимает значение &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;. Это событие используется для прерывания работы цикла.&lt;br /&gt;
&lt;br /&gt;
Обработчиков исключений в этом случае не требуется, если данные не будут найдены, то цикл не будет выполнен ни разу.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
    empname VARCHAR2(200);&lt;br /&gt;
    CURSOR c1 IS&lt;br /&gt;
        SELECT ename&lt;br /&gt;
            FROM scott.emp;&lt;br /&gt;
BEGIN&lt;br /&gt;
    OPEN c1;&lt;br /&gt;
        LOOP&lt;br /&gt;
            FETCH c1 INTO empname;&lt;br /&gt;
            EXIT WHEN c1%NOTFOUND;&lt;br /&gt;
            -- работа со значением empname&lt;br /&gt;
        END LOOP;&lt;br /&gt;
    CLOSE c1;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Использование указателей на курсоры ====&lt;br /&gt;
Для большей гибкости удобно вместо курсора использовать [[Указатель (тип данных)|указатель]] на курсор с разными курсорами. В таком случае курсор с запросом определяются неявно при вызове операции &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; для указателя на курсор с помощью предложения &amp;lt;code&amp;gt;FOR&amp;lt;/code&amp;gt;. Один указатель на курсор можно использовать со многими курсорами и, соответственно, со многими запросами.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
    TYPE GenericCursor IS REF CURSOR;&lt;br /&gt;
    с1 GenericCursor;&lt;br /&gt;
    empname VARCHAR2(200);&lt;br /&gt;
BEGIN&lt;br /&gt;
    OPEN c1 FOR SELECT ename FROM scott.emp;&lt;br /&gt;
        LOOP&lt;br /&gt;
            FETCH c1 INTO empname;&lt;br /&gt;
            EXIT WHEN c1%NOTFOUND;&lt;br /&gt;
            -- работа со значением empname&lt;br /&gt;
        END LOOP;&lt;br /&gt;
    CLOSE c1;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Использование связанных переменных ====&lt;br /&gt;
Как при использовании курсоров, так и при использовании указателей на курсоры рекомендуется при формировании запросов не включать туда конкретные [[Константа (программирование)|константы]] (кроме тех случаев, когда эти константы действительно будут сохраняться во всех подобных запросах). Связано это с тем, что при последовательном выполнении двух запросов, отличающихся только константой (например, &amp;lt;code&amp;gt;SELECT ename FROM employees WHERE id = 20&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;SELECT ename FROM employees WHERE id = 21&amp;lt;/code&amp;gt;), СУБД производит разбор каждого запроса отдельно, хотя на самом деле [[План выполнения запроса|план выполнения]] у таких запросов общий. Такие повторные разборы могут существенно снизить [[Производительность программного обеспечения|производительность]] приложения.&lt;br /&gt;
&lt;br /&gt;
Для предотвращения лишних разборов используется техника связанных переменных ({{lang-en|bind variables}}), то есть переменных непосредственно в теле запроса, значения которых подставляются только при открытии [[Курсор (базы данных)|курсора]] для запроса. Связанные переменные обозначаются именем, предварённым символом двоеточия. При открытии курсора значения переменных указываются с помощью предложения &amp;lt;code&amp;gt;USING&amp;lt;/code&amp;gt;. При первом выполнении участка кода, использующего технику связанных переменных, запрос будет разобран в СУБД, для него будет создан [[План выполнения запроса|план выполнения]] (это будет происходить сравнительно долго); при последующих выполнениях будет использоваться уже созданный план выполнения, и запрос будет быстро возвращать значения.&lt;br /&gt;
&lt;br /&gt;
Пример функции со связанными переменными:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
FUNCTION get_employee_name (empid INTEGER, empcity VARCHAR2) RETURN VARCHAR2 IS&lt;br /&gt;
    TYPE GenericCursor IS REF CURSOR;&lt;br /&gt;
    c1 GenericCursor;&lt;br /&gt;
    empname VARCHAR2(200);&lt;br /&gt;
BEGIN&lt;br /&gt;
    OPEN c1 FOR &amp;#039;SELECT ename FROM employees WHERE id = :id AND city = :city&amp;#039; USING empid, empcity;&lt;br /&gt;
        -- цикл не используется, так как запрос вернёт не более одной строки&lt;br /&gt;
        FETCH c1 INTO empname;&lt;br /&gt;
    CLOSE c1;&lt;br /&gt;
&lt;br /&gt;
    RETURN empname;&lt;br /&gt;
END get_employee_name;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Неявное определение курсора в цикле ====&lt;br /&gt;
Иногда вместо того, чтобы объявлять курсор или указатель на него, удобно воспользоваться неявным определением курсора и неявным определением переменной типа [[Запись (тип данных)|запись]] (&amp;lt;code&amp;gt;RECORD&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
&lt;br /&gt;
BEGIN&lt;br /&gt;
    FOR rec IN (SELECT id, ename, 1 AS value FROM employees) LOOP&lt;br /&gt;
        dbms_output.put_line(rec.id || &amp;#039;: &amp;#039; || rec.ename);&lt;br /&gt;
    END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пакетный запрос многих строк ====&lt;br /&gt;
При запросе большого числа строк можно увеличить производительность, если вместо поочерёдного зачитывания строк результата, зачитать их всех сразу, значительно снизив тем самым количество переключений контекста от PL/SQL к SQL и обратно. Для пакетного чтения необходимо снабдить оператор &amp;lt;code&amp;gt;FETCH&amp;lt;/code&amp;gt; инструкцией &amp;lt;code&amp;gt;BULK COLLECT&amp;lt;/code&amp;gt;. Данные при этом должны записываться не в переменные, а в [[Ассоциативный массив|ассоциативные коллекции]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
    TYPE GenericCursor IS REF CURSOR;&lt;br /&gt;
    c1 GenericCursor;&lt;br /&gt;
    TYPE VarcharTable IS TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER;&lt;br /&gt;
    -- объявили тип данных &amp;quot;Таблица строк&amp;quot;, элементы которой нумеруются числами&lt;br /&gt;
    empnames VarcharTable;&lt;br /&gt;
    -- объявили переменную созданного типа&lt;br /&gt;
BEGIN&lt;br /&gt;
    OPEN c1 FOR SELECT ename FROM employees;&lt;br /&gt;
        FETCH c1 BULK COLLECT INTO empnames;&lt;br /&gt;
    CLOSE c1;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;#039;&amp;#039;&amp;#039;Пакетный запрос многих значений&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Также можно запросить много значений и поместить их в заранее подготовленную коллекцию (или несколько коллекций). Для этого у нас должен быть объявлен соответствующий тип коллекции, например коллекция строк: &amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create or replace type t_str_coll as table of varchar2(2000 char);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Тогда, мы можем поместить все ename из таблички employees в нашу коллекцию таким образом:&amp;lt;syntaxhighlight lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
  l_str_coll t_str_coll;&lt;br /&gt;
BEGIN&lt;br /&gt;
  SELECT t.ename&lt;br /&gt;
    BULK COLLECT &lt;br /&gt;
    INTO l_str_coll&lt;br /&gt;
    FROM employees t;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выполнение операций DML ====&lt;br /&gt;
Операции [[DML]], как правило, выполняются точно так же, как и в SQL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
&lt;br /&gt;
BEGIN&lt;br /&gt;
    UPDATE employees SET hire_date = SYSDATE WHERE id != 1;&lt;br /&gt;
    INSERT INTO employees (name, city) VALUES (&amp;#039;SMITH&amp;#039;, &amp;#039;Тикси&amp;#039;);&lt;br /&gt;
    COMMIT;&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамический SQL ===&lt;br /&gt;
{{main|Динамический SQL}}&lt;br /&gt;
==== Динамические запросы ====&lt;br /&gt;
Для большей гибкости часто статические запросы заменяются запросами, формируемыми динамически. Недостаток динамического SQL в том, что динамические запросы, разумеется, не могут быть проверены на этапе компиляции. Если, например, используемой в запросе таблицы не существует, то при выполнении операции &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; возникнет исключение.&lt;br /&gt;
&lt;br /&gt;
Классическая задача, требующая применения динамического конструирования SQL-запросов, — отчёты в [[интерфейс]]ах, где пользователь может выбрать разные условия, по которым следует сформировать отчёт.&lt;br /&gt;
&lt;br /&gt;
Ниже приведён анонимный блок кода, который в зависимости от некоего условия запрашивает имя сотрудника либо по ключу, либо по городу.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
    TYPE GenericCursor IS REF CURSOR;&lt;br /&gt;
    c1 GenericCursor;&lt;br /&gt;
    sel VARCHAR2(4000);&lt;br /&gt;
    bind_var VARCHAR2(200);&lt;br /&gt;
    result VARCHAR2(200);&lt;br /&gt;
BEGIN&lt;br /&gt;
    sel := &amp;#039;SELECT name FROM employees WHERE 1 = 1&amp;#039;;&lt;br /&gt;
    IF ... THEN&lt;br /&gt;
        sel := sel || &amp;#039; AND id = :1&amp;#039;;&lt;br /&gt;
        bind_var := 12;&lt;br /&gt;
    ELSE&lt;br /&gt;
        sel := sel || &amp;#039; AND city = :1&amp;#039;;&lt;br /&gt;
        bind_var := &amp;#039;Магадан&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
&lt;br /&gt;
    OPEN c1 FOR sel USING bind_var;&lt;br /&gt;
        FETCH c1 INTO result;&lt;br /&gt;
    CLOSE c1;&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Динамические DML- и DDL-операции ====&lt;br /&gt;
Динамические операции [[Data Manipulation Language|DML]] и [[Data Definition Language|DDL]] выполняются с помощью оператора &amp;lt;code&amp;gt;EXECUTE IMMEDIATE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;plsql&amp;quot;&amp;gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
&lt;br /&gt;
BEGIN&lt;br /&gt;
    EXECUTE IMMEDIATE &amp;#039;DELETE FROM employees&amp;#039;;&lt;br /&gt;
    EXECUTE IMMEDIATE &amp;#039;DROP TABLE employees&amp;#039;;&lt;br /&gt;
    -- COMMIT или ROLLBACK не нужен, потому что DDL-операция завершила транзакцию&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Допускается использование связанных переменных, их значения также указываются в предложении &amp;lt;code&amp;gt;USING&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{Примечания}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Oracle Database]]&lt;br /&gt;
[[Категория:Процедурные расширения SQL]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Lê Lợi (bot)</name></author>
	</entry>
</feed>