Язык pl sql oracle

Основы PL SQL: структура, функции, триггеры, переменные, записи

PL/SQL (Programming Language for SQL) — язык программирования от компании Oracle, предоставляющий средства для сложной обработки данных. В этой статье мы рассмотрим основы PL/SQL. Начнём с программных единиц.

Программные единицы PL/SQL

К программным единицам в PL/SQL относят:

1. Процедуру — подпрограмму, выполняющую специфическое действие (CREATE PROCEDURE);

2. Функцию — подпрограмму, вычисляющую значение (CREATE FUNCTION).

3. PL/SQL-пакеты — объект БД, группирующий логически связанные типы, подпрограммы и программные объекты PL/SQL. Как правило, пакеты состоят из 2 частей — тела и спецификации. Спецификация представляет собой интерфейс с вашими приложениями (объявляет типы, константы, переменные, исключения, подпрограммы, курсоры — всё, что доступно для использования в пакете). Вторая часть — это тело пакета, полностью определяющая подпрограммы и курсоры, реализуя тем самым спецификацию пакета.

4. Динамический SQL :

a. Native Dynamic SQL (NDS);

6. Триггеры — хранимые процедуры особого типа, которые юзер не вызывает непосредственно, т. к. их исполнение обусловлено действиями по модификации данных. Триггеры бывают разные: BEFORE INSERT, BEFORE UPDATE, AFTER INSERT и пр.

8. Хинты либо подсказки (Oracle Hints) — средства, которые позволяют оказывать явное влияние на план запроса. Подсказки определяют общие подходы и цели, оптимизирующие план исполнения запроса, в том числе методы и правила доступа к данным (например, указание метода и порядка соединения таблиц, индекса для доступа к таблице).

Блочная структура PL/SQL

В блоке PL/SQL может содержаться до 4-х разделов, но лишь один считается обязательным.

Давайте посмотрим на структуру PL/SQL-блока для процедуры:

Следующее изображение — это пример процедуры, содержащей все 4 раздела:

Под хранимой процедурой понимают некоторый перечень инструкций, которые написаны на PL/SQL. Вызов такой процедуры обеспечивает выполнение содержащихся в этой процедуре инструкций. Сама она хранится в БД, поэтому и считается хранимой. Состоит из тела и спецификации.

Спецификация содержит имя процедуры, а также описание её выходных и входных данных, которые являются формальными параметрами либо формальными аргументами. Когда при вызове процедуры указывают параметры командной строки либо иные входные данные, указанные значения называют фактическими параметрами/фактическими аргументами.

Рассмотрим пример спецификации:

В примере выше перед нами процедура с 3-мя формальными параметрами. IN после имени параметра значит, что в процессе вызова процедура может из данного параметра считать входное значение. OUT значит, что процедура может применять этот параметр в целях возврата значения в ту программу, из которой она вызывалась. Комбинация IN OUT значит, что параметр может использоваться в качестве передачи значения процедуре, а также в целях возврата значения.

Что касается тела процедуры, то это блок кода PL/SQL.

Хранимые функции

Функция PL/SQL напоминает процедуру PL/SQL: у неё тоже есть тело и спецификация. Основное различие — функция нужна для возврата значения, которое можно применять в более крупном операторе SQL.

Триггеры

Триггером называют процедуру PL/SQL, выполняемую автоматически, когда происходит некоторое событие, которое называется триггерным событием.

К примеру, мы можем писать триггеры, которые срабатывают в процессе выполнения над таблицей операций UPDATE, INSERT либо DELETE; во время выдачи команд DDL; во время входа пользователя в систему либо его выхода; во время запуска либо остановки БД; во время возникновения ошибок.

Существуют 3 различия между процедурами PL/SQL и триггерами:

1. Триггеры невозможно вызвать из кода программы. Они вызываются автоматически как ответ на некоторое событие.

2. У триггеров нет списка параметров.

3. Спецификации триггера и процедуры немного отличаются.

Переменные в PL/SQL

Переменными называют именованные контейнеры. Они способны содержать информацию разных видов. С учётом помещаемой информации данных они имеют разные типы данных, а чтобы отличать эти данные друг от друга, присваиваются имена. К примеру, числа в PL/SQL хранятся в переменных типа NUMBER, текст — в переменных CHAR либо VARCHAR2. Что касается синтаксиса объявления переменной, то в PL/SQL он имеет любую из нижеперечисленных форм записи:

Здесь имя_переменной — любой правильный PL/SQL идентификатор. Такой идентификатор должен:

1. Иметь в длину не больше 30 символов, причём не иметь в записи пробелов и знаков табуляции.

2. Начинаться с буквы.

3. Состоять лишь из букв, цифр 0-9, символа подчеркивания, знака доллара и знака фунта.

4. Не совпадать с зарезервированными словами SQL и PL/SQL, имеющими спецзначение. Пример неправильной записи для переменной — слово BEGIN, обозначающее начало выполняемой секции основного PL/SQL-блока.

Следующее, это тип_данных — любой допустимый тип данных в SQL либо PL/SQL. Здесь обратите внимание, что модификатору NOT NULL требуется, чтобы переменная имела значение. И если модификатор указан, то переменной должно присвоиться значение по умолчанию.

Объявляем константы PL/SQL

Запись объявления константы выглядит следующим образом:

В отличие, скажем, от тех же переменных, константам обязательно присваивается значение, причём это значение нельзя будет поменять в течение всего срока жизни константы. При этом константы весьма полезны при поддержании безопасности и дисциплины во время разработки приложений повышенной сложности. К примеру, если вы желаете гарантировать, что PL/SQL-процедура не будет модифицировать данные, передаваемые ей, то вы можете объявить их константами. А если процедура всё-таки попытается модифицировать эти данные, PL/SQL возбудит исключение.

Записи в PL/SQL

Говоря о записи в PL/SQL, мы говорим о наборе данных базовых типов. К записи мы можем обращаться, как к единому целому. При этом для доступа к отдельным полям записи используют нотацию имя_записи_имя_поля. Записи бывают одного из 3-х нижеперечисленных типов:

2. Cursor-based (основанные на курсоре). Что касается полей этих записей, то они совпадают по имени, порядку и типу с заключительным списком столбцов в курсорном операторе SELECT.

3. Programmer-defined (определённые программистом). Тут речь идёт про записи, тип которых определяет программист, то есть вы сами.

Record PL/SQL

Давайте посмотрим, как применять спецификатор записи Record в PL/SQL с синтаксисом.

Record (запись) — это группа связанных элементов данных, которые хранятся в полях, причём каждая имеет своё имя и тип данных. При этом мы можем применять Record как переменную, способную содержать строку таблицы либо некоторые столбцы из строки таблицы.

Определяем и объявляем Record в PL/SQL

Посмотрим на синтаксис объявления переменной в PL/SQL и определения типа Record:

Мы видим следующие параметры:

1) type_rec_name – имя конкретного типа Record;

2) var_rec – имя переменной Record-типа;

3) field_1, field_2,… field_n – поля Record-типа;

4) datatype – тип данных для полей Record-типа. Может быть любой из списка:

При подготовке статьи использовались следующие материалы:

Не упустите возможность приобрести курс с большой скидкой и перенять Best Practices у лучших!

Источник

Хорошие привычки в PL/SQL

Стандарт

Управление кодом

Было несколько статей на тему миграции баз и версионность. Статьи бесспорно хороши, но только когда у вас несколько десятков табличек. У нас же 200к строк PL/SQL кода (число других объектов сопоставимо с этим) и команда из 10 человек.
Сначала пытались использовать для контроля всего связку RequesitePro + ClearQuest + ClearCase, но после непродолжительного времени от СС отказались и заменили на git с локальным хранилищем на gitorious.
Разные части приложения разделили на разные репозитории. Создали отдельные репозитории для модификаций для отдельных клиентов.
Подход к файлам следующий: есть baseline и есть патчи к нему, со временем и то и другое обновляется.

Написание кода

Редакторский дайджест

Присылаем лучшие статьи раз в месяц

Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.

Похожие публикации

От Oracle Database 12c EE к PostgreSQL, или основные отличия PostgreSQL при разработке под IEM-платформу Ultimate

Выходим на уровень эксперта! 50 оттенков экзамена 1Z0-047 (сертификация Oracle Database SQL Certified Expert)

Представление данных SAP R/3 в Oracle Database с помощью SAP Java Connector

Курсы

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Минуточку внимания

Комментарии 60

Да, да, да и ещё раз Да. Верным путём.

Тэги тока поправьте, могут не найти.

Форматирование кода у Вас (а именно отступы) — вырви глаз 🙂

Кстати, объясните подробнее про помещение операторов SQL в отдельные процедуры и функции. Какие это дает преимущества?

>> Кстати, объясните подробнее про помещение операторов SQL в отдельные процедуры и функции. Какие это дает преимущества?

Первое и очевидное, это то что достаточно часто операторы повторяются в коде.

А второе и самое главное, что при изменении требований к тому что возвращает оператор можно менять процедуры и функции не перекомпилируя другие объекты (они не становятся инвалидными). То есть можно прямо на работающей системе заменить функцию и при следующем вызове она будет использована (естественно стоит ее протестить и не забыть приписать CREATE OR REPLACE).

По-моему в ваших словах есть некоторое противоречие.
С одной стороны известно что переключение контеста PLSQL / SQL дает определенный оверхед и вы справедливо рекомендуете этого избегать.
С другой стороны вы рекомендуете оборачивать SQL операторы в PLSQL.

>>помещение операторов SQL в отдельные процедуры и функции. Какие это дает преимущества?
Действительно интересный вопрос.

Мне доводилось над этим задумываться, когда я видел, как эту практику применяет и сам Oracle corp в некоторых своих решениях. Для каждого модуля они оформляют пакетик, в который выносят все SQLчики. Причем не сказал бы, что эти пакетики действительно повторно используется. Если бы их готовили как API для повторного использования, наверное следовало бы резать не по модулям, а по сущностям. API для работы с товарами, API для работы со складами. Так нет же. Они нарезают их по модулям. Делают пакет для формы ввода накладной, пакет для батча расчета потребности. Оба пакета могут содержать совершенно одинаковые DML, при этом в обоих пакетах нет не реализовано ни грамма логики.

Однако при такой организации оказывается достаточно удобно выявлять зависимости, проводить обратный инжиниринг. Уточнение схемы данных приводит к ревалидации и повредившиеся модули видно сразу, а не в процессе их исполнения, сразу же их можно и подправить, без пересборки приложения. Опять же, самый простой способ стабилизировать план запроса — переписать его, захинтовать. Но ели руководствоваться именно этими тезисами, впору усомниться в целесообразности выноса логики на приложение.

PLSQL — дает возможность использовать процедурное программирование на стороне СУБД.

Соответственно PLSQL можно применять там где нельзя обойтись одним SQL, например: прочитать файл с сервера и загрузить его в таблицу, выполнить HTTP запрос, передав данные из БД и т.п. Бизнес логика иногда выносится на уровень СУБД — SQL тут не хватит.

Тут не может быть 2х мнений. Если писать бизнес-логику на языках общего назначения, то поддерживать ее гораздно проще.
Понимаете, компилируемые языки, юнит-тесты, простые решения, отсутствие возможности что-то поправить на production сервере, все это значительно сокращает количество ошибок и располагает писать надежный код.
И, о ужас, вы сможете отказаться от использования Oracle, потому что не будете завязаны на конкретную СУБД.

Я даже позволю себе лирическое отступление.
Когда-то давно, ну, лет может 5-8 назад не было такого количества разных решений для работы с данными, никто не знал ни про какие map/reduce и nosql решения.
Зато был Oracle, который представлялся этакой серебрянной пулей и волшебно решал все проблемы с производительностью, стоил он, да и стоит сейчас тоже «волшебно».
Соотвественно была построена целая индустрия людей, которые знали только Oracle и гребли немеряно денжищ на этом.
Сила бренда по-прежнему велика, но зачем писать новые проекты под Oracle?
К сожалению, есть много организаций, которые рефлексивны по сути, например, банки, гос. структуры, корпорации-монстры и, единожды подсев, они
уже плотно сидят на этой Oracle игле.

Сейчас Вы можете написать приложение под MySql, PostgreSql, даже NoSql и оно будет не менее надежным и производительным, это почерпнуто из опыта.

А vожете привести, пожалуйста, пример самой сложной в вашей жизни бизнес-логики?

Уж поверьте, «корпорации-монстры», перед тем, как «сесть на иглу», сотни раз просчитают, в частности стоимости других решений. И как раз, в «серьезном бизнесе» решения от Oracle очень тесно идут там где надо «рука об руку» и с OpenSource-решениями, и с решениями сторонних фирм, и с собственными разработками.

Ох. невозможно написать универсальное приложение, которое одинаково эффективно будет работать на всех СУБД. Лучшие умы Вселенной пытались, (не я, не, я идиод), но не выйдет. Везде есть свои особенности, я на двух базах нахлебался уже (Oracle ft. MSSQL)

А вообще, с возрастом проходит желание делать такие жесткие и однозначные выводы.

«Понимаете, компилируемые языки, юнит-тесты, простые решения, отсутствие возможности что-то поправить на production сервере, все это значительно сокращает количество ошибок и располагает писать надежный код.»

Fokken fok! PL/SQL компилируемый язык, с мощной возможность отладки.

«Невозможно написать универсальное приложение, которое одинаково эффективно будет работать на всех СУБД»

1) связанные переменные. Они во всех базах в запросах указываются по-разному. Разумеется, можно препарсер заделать, как у нас, но это так себе идея.
2) набор функций в БД, например в Oracle очень хорошо сделаны аналитические функции, а в MSSQL гораздо неприятнее с этим. То есть лично мне приходится так писать запросы, чтобы они работали одинаково в обоих базах. Соответственно, они менее эффективно работают в обоих базах. (Можно я не буду приводить примеры?)
3) Запросы можно составлять, с учетом конкретной архитектуры, например, если я знаю, что на сервере есть Parallel Query Option, то я и запрос напишу соответственно этому.
4) identity vs sequences — головная боль, в MSSQL есть ограничение на отключение identity в одной сессии и одновременно.

Сливают карму (по себе сужу), когда я делаю резкие выражения, типа я д’Артаньян, а остальные — не д’Артаньяны, а за что Вам слили, я не в курсе.

Знаешь, я настолько олдфаг и слоупок, что для меня NoSql, это Adabas, в нем не было SQL, поэтому я просто не понимаю, о чем ты пишешь тут. Извини конечно.

2. Ну, FIRST_VALUE, LEAD, LAG — вот их очень часто. Специфика работы такая

4. В многопользовательской среде, это действительно проблема. Но в общем,
зависит от дизайна базы.

Вообще кажется до меня дошло, что такое NoSQL в вашем понимании.
Ну может быть, конечно, но отказоустойвость, масштабируемость у Oracle очень на высоте. Не знаю, я конечно мхом не порос еще, но я не видел (никто не показывал) какого-то NoSQL, который был бы достойной заменой RDBMS.

Насчет масштабируемости Оракла не буду врать, не в курсе, видел его в продакшене только на мощных сановских серверах.

Я не против Оракла, просто мне думается, что большинство решений делать на нем проекты принимается под влиянием бренда или откатов, без всякого технического обоснования.

«большинство решений делать на нем проекты принимается под влиянием бренда или откатов, без всякого технического обоснования.»

Да оно вообще всё так делается. Хотя, Oracle не настолько и дорог, чтобы им не пользоваться. Не говоря уже об «XE»-версиях.

Fafnir, не надо насчет «танцев с бубном». Если бы вы сами действительно достаточно «натанцевались с бубном в 21 и в 20 веках», вам было бы хорошо известно, что в достаточно более-менее серьезных проектах обычно существует очень много как горизонтальных так и вертикальных слоев бизнес-логики.

Да и общий обьем этой бизнес-логики такой, что не уместится сразу в голове у одного программиста. Много вы знаете программистов, которые одновременно бы являлись и высококлассными администраторами БД, и обладали бы знаниями бухучета на уровне хорошего аудитора, и понимали бы движения средств на уровне финдиректора фирмы, и отлично знани бы организационное взаимодействие между подразделениями фирмы, и владели бы всей информацией по логистическому движению, и знали бы о различных «тонкостях ведения бизнеса», владели бы отчетность и документооборотом, и при этом не забывая как писать высококлассный, надежный код, и более того, при этом держа в уме нехилую структуру БД и владея техниками оптимизации?

Я уверяю Вас, даже обладая интелектом Эйнштейна Вы сядете в лужу, пытаясь запихнуть всю бизнес-логику внутрь одного монстробразного неповоротливого приложения. А если и попытаетесь, то все равно у вас ничего не выйдет, потому что «O, Surprise», зачастую сами части этой бизнес-логики могут быть так разнесены даже географически и по часовым поясам и даже (не поверите… законодательно, то есть у вас будут реально разные части бизнес-логики, работающие по разному отражая требования разного законодательства), что Вам наверное даже это трудно будет представить!

Ну-ка? А теперь скажите, о чем думать программисту, о том, что на разных филиалах налоги считаются по разному алгоритму или о том на какой таблице какой индекс и какую одну таблицу с десятками миллионов записей как правильно сджойнить с другой таблицей с миллионами записей так чтобы сразу не парализовать работу?

Но это еще не все! А теперь, давайте взглянем на то, что над крупным проектом работаете не вы один а десятки других программистов и на логику БД завязаны сотни тысяч строк кода. Я умышленно сказал на логику БД а не на структуру БД.

Потому что если бы весь этот код был завязан на структуру БД, то у вас бы просто исчезла такая возможность что-то менять в структуре БД. А любой сбой в этих сотнях тысяч строк кода стоит миллионы денег, не забываем об этом, поэтому нельзя ничего из этого кода выводить из работоспособного состояния.

Поэтому выведение разумной части бизнес-логики на уровень СУБД, это далеко не прихоть, а суровая необходимость.

А в некоторых случаях единственно реально-доступная возможность, особенно, когда специально выделенный DBA занимается оптимизацией выполнения запросов, огранизацией хранения, резервирования, измением структуры, отказоустойчивостью БД, не вдаваясь в бизнес-логику, в которой он все равно нифига не поймет, в силу некомпетенции и в силу того, что он не смог бы ее окинуть взглядом. А созданием например, рабочего места для финдиректора, занимается программист, знающий что такое налоги, счета, договора и прочие вещи, в которые никогда не будет лезть DBA. А DBA может легко изменить структуру БД, например, по просьбе другого программиста, занимающегося, к примеру внутренней логистикой, не поломав при этом интерфейс БД.

Поэтому, пожалуйста, не делайте поспешных заявлений по поводу тех вещей в которых мало разбираетесь.

>>DBA занимается… измением структуры… не вдаваясь в бизнес-логику

Я с трудом представляю, как такое возможно. Только если структура не связана с бизнес-логикой, а это уже скорее NOSQL-решение.

То что вы описали гораздо проще решается трехзвенкой: абстрактное хранилище, которое вообще никак не завязано на бизнес-логику. Объектно-реляционная БД например. DBA будет проще его админить и сложнее поломать. Следующий уровень — вся бизнес логика. И последний — то самое отображение бизнес логики в виде красивой диаграмки для директора. Или отчета для менеджера. Смысл в том что нижние уровни не знают ничего о верхних. Соответственно и обслуживающие их работники не должны особо вникать в работу друг друга.

Если же хранилище перемешано с бизнес-логикой (Таблицы + ХП), а часть логики еще и в клиентском приложении — это поддерживать гораздо сложнее.

Несомненная область применения ХП — автоматизация абстрактных операций по обслуживанию хранилища.

Также, вынос части логики в ХП полезен в многопользовательских двухзвенных системах, т.к. здорово повышает производительность клиентского приложения за счет выноса сложных операций с данными на сервер.

Возможно я немного неточно выразился, насчет «не вдавание DBA в бизнес-логику». PL/SQL-процедуры и пакеты пишут программисты, хорошо владеющие бизнес-логикой верхнего уровня, а DBA им помогает сделать оптимально работающими.

Так, DBA работает с оптимизацией аггрегационных запросов которые оперируют с некоторым полем некой большой таблицы, данные в этом поле меняются некоторым job-ом, который запускается в конце каждого месяца. (DBA не сильно вдается в семантику что означает данное поле, но он помогает программистам сделать работу быстрой и надежной). Так например, возможным решением будет написание еще одной процедуры, запускающейся из первой, которая будет сохранять аггрегированные данные для дальнейшего интенсивного использования. (но это конечно на пальцах).

Насчет трехзвенки: Это хорошо, но к сожалению «трехзвенка не всегда серебрянная пуля».

какую одну таблицу с десятками миллионов записей как правильно сджойнить с другой таблицей с миллионами записей так чтобы сразу не парализовать работу?

Поверьте, я на любую проблему могу взглянуть «под другим углом» (кроме Oracle, мне известно дохрена еще разных технологий, а мозги у меня еще не настолько закостенели до состояния неспособности перерабатывать новую информацию, на пенсию я пока не собираюсь, btw).

И я из практики знаю, что существует оргомная масса задач, когда «умное хранилище» более оптимально чем «просто хранилище данных». Потому что я могут вам привести миллион примеров, когда добавление десяток-другой строчек в логику БД на PL/SQL можно эквивалентно решить, но решить десятком-другим ТЫСЯЧ СТРОК кода на прикладном уровне (разбросанного до кучи по разным модулям, поддерживаемым разными программистами).

Что и на что Джойнить/Не Джойнить вопрос оптимизации физической работы с БД, а не логической.

Простой пример:
Вам надо получить состояние взаиморасчетов с контрагентами по состоянию на конец позапрошлого месяца. Причем не просто так, а для дальнейшей обработки.
Вроде, плевое дело, в приложении пишем SQL-запрос, аггрегирующий проводки (к примеру).
Замечательно, когда данных мало, можно просто саггрегировать проводки, по конец заданного месяца и все будет замечательно работать. И этот кусок кода будет хорошо работать пока база не разрослась и количество проводок не стало исчисляться миллионами.
Ну, что все очень просто, скажете, достаточно изменить физическую структуру (где-то достаточно добавить готовое вычисленное для ускорения состояние взаиморасчетов на концы определенных периодов, где-то что-то добавить в таблицу, где-то что-то выкинуть..).
Но, вот тут и возникает ОФИГЕННАЯ СЛОЖНОСТЬ: запросов, работающих с физической структурой проводок туева хуча в сотнях тысяч строк, причем сбой в любой из них — сразу милионные убытки!

Так что, у вас героизма очень-бы поубавилось, если вас заставить отыскать в сотне-другой тысяч строк все места где хардкодом прошиты SQL-запросы к физической структуре. Большинство этих тысяч строк, заметим, даже не вы мантейните, а другие программисты, причем места эти могут быть настолько б-гом забытые, что даже «отвественные за них программисты» вам наверное скажут «да, меняй, вроде ничего не должно порушиться».

Так что еще раз вам повторяю — логика в СУБД — это не прихоть, а иногда просто необходимость.
Это другая методология взаимодействия с БД: не работа не с физической структурой (таблицами и полями), а работа с хранилищем как логической структурой — для вас БД это не хранилище таблиц и полей, а хранилище сущностей типа договоров, балансов, проводок (причем сущностей которые можно не только получить и записать, но и обладающие достаточно сложной внутренней логикой). Причем как оно будет отображено на «физический уровень хранения» может десять раз меняться.

А Теперь развею ваши иллюзии насчет логики БД и PL/SQL. Вы скажете, что эту самую логику отображения логических сущностей на физические таблицы можно выполнять и на прикладном уровне?

1) Да, конечно, можно. Но неоптимально, потому что две строки PL/SQL

100-1000 строк C++ (при этом не забываем, сколько потенциальных ошибок в них может содержаться, а каждая «ошибочка» стоит дохрена бабла).

2) Более существенны в «серьезном бизнесе» фактор «гетерогенности среды».
Представьте себе, с одной и той же базой данных работают из разных приложений на разных языках и разных местах.
Например, для клиентов существует «веб-кабинет клиента», где он может видеть относящуюся к мену часть работу через отдельный раздел веб-сайта (сайт писан на PHP).
Департамент логистики работает с данными через какую-то свою только им понятную хрень писанную каким-то тамошним умником на питоне.
С проводками по банку работает программа связанная с клиент-банком писанная на C.
Из склада с БД работают наладонники снабженные сканнером штрих-кода на которых крутиться Java-приложение (причем это Java-приложение писала сторонняя фарма)… и т.д., список можно продолжать.
А теперь, подумайте, вообще это реальная задача — взять и изменить просто так физическую структуру БД, НЕ СЛОМАВ ПРИ ЭТОМ ВСЕ?
Сможете ли вы легко «денормализовать данные» в такой реальной гетерогенной среде?
Боюсь, увы, молодой человек, вы сильно переоцениваете свои силы!

Да, наличие логики на уровне БД — это действительно другая методология (вам, как я вижу, методология неизвестная), но она действительно очень часто является чуть ли не лучшим из приемлемых решений.

Источник

Поделиться с друзьями
admin
Оцените автора
( Пока оценок нет )
Как переводится?
Adblock
detector