sql: Как проверка данных выполняется с помощью хранимых процедур? - PullRequest
3 голосов
/ 18 апреля 2011

"Хранимые процедуры обычно используются для проверки данных или для инкапсуляции больших сложных инструкций по обработке, которые объединяют несколько запросов SQL."

Говорит этот Oracle ссылка .Так может ли кто-нибудь помочь мне понять, приведя примеры из реальной жизни, как хранимые процедуры используются для проверки данных?

Ответы [ 3 ]

4 голосов
/ 18 апреля 2011

Проверка может означать несколько вещей и может выполняться в базе данных различными способами:

  • Типы данных столбцов сами по себе являются формой проверки: столбцы NUMBER принимают только действительные числа и т. Д.
  • Ограничения первичного ключа, уникального и внешнего ключа выполняют проверку
  • Проверочные ограничения выполняют другие простые однострочные проверки, такие как:
    • END_DATE> START_DATE
    • SALARY>0
    • ЗАДАНИЕ = ПРОДАВЕЦ ИЛИ КОМИССИЯ НЕДОСТУПЕН

Однако существуют более сложные правила проверки, которые не могут быть выполнены ни одним из вышеперечисленных, например:- SALARY <= (ВЫБЕРИТЕ max_sal FROM config_table) - emp.start_date BETWEEN start_date AND end_date отдела, которому они назначены </p>

Существуют различные способы применения этих правил, включая триггеры базы данных, но часто предпочтительным методом являетсясоздать хранимую процедуру, часто называемую «API», для выполнения проверки и действия, например,

PROCEDURE insert_emp (...) IS
    ...
BEGIN
    -- Validate
    -- 1) Salary less than max
    SELECT max_sal
    INTO   l_max_sal
    FROM   config;
    IF p_sal > l_max_sal THEN
        error_pkg.raise_error ('Salary is too high');
    END IF;
    ...
    -- Insert
    INSERT INTO emp (...) VALUES (...);
END; 

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

3 голосов
/ 19 апреля 2011

В идеальном мире ваша СУБД по вашему выбору будет реляционно полной, что позволит вам писать ограничения произвольной сложности и поддерживать множественное присваивание, чтобы позволить вашей базе данных постоянно обновляться (т.е. без откладывания или отключения ограничений), используя простые операторы,В реальном мире у нас есть SQL.

Идеальный продукт SQL будет соответствовать стандарту Full SQL-92: поддерживать CREATE ASSERTION (ограничения уровня схемы), разрешать подзапросы в ограничениях CHECK и поддерживать отсрочкуограничения внутри транзакции, позволяющие обновлять базу данных без отключения ограничений.К сожалению, Oracle еще не достигла такого уровня функциональности.Поэтому в реальном мире нам иногда приходится прибегать к процедурному коду для «управления» обновлениями при сохранении целостности данных.

Рассмотрим, например, истинные отношения один к одному, достаточно распространенные, с бизнес-правилами.следующим образом:

База данных содержит сведения о сотрудниках и проектах в трех версиях: EMP, PROJ и EMP_PROJ.В каждом проекте должен быть хотя бы один сотрудник, и каждое вложение проекта должно относиться к существующему проекту.Когда проект создается, к нему должен быть одновременно подключен как минимум один сотрудник.

В Oracle нельзя написать ASSERTION или CHECK для применения ограничений между таблицами, поэтомув этом случае способность откладывать ограничения не имеет большого значения.

Один из подходов, который может помочь написать PROCEDURE с соответствующими параметрами для создания проекта и назначения одного сотрудника для проекта.Такая процедура должна в следующем порядке (псевдокод):

1) начинать транзакцию;

2) вставлять в PROJ;

3) вставлять в EMP_PROJ;

4) Проверка данных, которые не соответствуют условным ограничениям, например,

EXISTS (
        SELECT * 
          FROM PROJ
         WHERE NOT EXISTS (
                           SELECT * 
                             FROM EMP_PROJ
                            WHERE EMP_PROJ.project_code = PROJ.project_code
                          )
       );

5) Если при проверке обнаруживаются недопустимые данные, в противном случае выполняется откат транзакции.

Если ограничения кусаются, то транзакция откатывается и целостность данных сохраняется (хотя, возможно, вы захотите обработать такой сбой проверки более изящно:)

Аналогичная процедура потребуется для удаления сотрудника изпроект по предотвращению сценария, когда последний оставшийся назначенный сотрудник удаляется из проекта (следует ли исключить удаление сотрудника или следует удалить проект? спросите своего дизайнера:)

Поскольку целостность данных может быть обеспечена тольковыполняя такой процедурный код, удобно для всех инкапсулировать его в объекте PROCEDURE в базе данных, а затем предоставить 'execute' pдарит пользователям PROCEDURE (вместо предоставления расширенных привилегий для базовых таблиц).Чтобы заставить группу пользователей (например, приложения конечного пользователя) использовать только PROCEDURE для обновления данных, их права на обновление для базовых таблиц должны быть аннулированы.Это может потребовать предоставления дополнительных «вспомогательных» функций, например, для назначения сотрудников на проект и удаления проекта.Если вы купите в школе «все доступ к базе данных через хранимые процедуры», вы все равно будете этим заниматься.

3 голосов
/ 18 апреля 2011

Проверка данных происходит потому, что для передачи данных в хранимую процедуру это делается с помощью параметров, которые явно установлены на типы данных Oracle (или пользовательские типы, которые также основаны на типах данных Oracle). Выполняется только проверка типа данных - при необходимости необходимо провести более глубокую проверку (т. Е. Проверка десятичных знаков в типе данных NUMBER). Параметризованные запросы, как правило, более безопасны от внедрения SQL, но на самом деле это зависит от параметров и от того, что делает запрос.

 CREATE OR REPLACE PROCEDURE example (IN_VALUE NUMBER) IS

 BEGIN

   SELECT t.*
     FROM TABLE t
    WHERE t.column = IN_VALUE;

 END;

В этом примере отправка VARCHAR / строки приведет к ошибке - все, кроме того, что поддерживает NUMBER, приведет к ошибке. И вы получите ошибку, если тип данных IN_VALUE не может быть неявно преобразован в тип данных TABLE.column.

Хранимая процедура инкапсулирует транзакцию, которая позволяет выполнять сложные инструкции обработки (то есть более одного запроса SQL). Обработка транзакций (т. Е. Необходимость явно указывать «COMMIT» или «ROLLBACK») зависит от настроек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...