Увеличьте ограничение целостности родительского ключа в процедуре для каждого столбца

У меня есть следующий код в пакете, который вставляет данные в таблицу.

Я могу получить родительский ключ не найден исключение. Как я могу получить сообщение о нарушении ограничений для каждого столбца? Например, если proj_id нарушается, тогда возникает исключение, если proj_code нарушается, а затем поднять еще одно исключение.

PROCEDURE add_project(
     p_proj_id              project.proj_id%TYPE,
     p_proj_desc        project.proj_desc%TYPE,
     p_proj_code  project.proj_code%TYPE,
     p_proj_date      project.proj_date%TYPE
     )
      IS
    parent_not_found exception;
    pragma exception_init(parent_not_found, -2291);
     BEGIN
        INSERT
            INTO projects (proj_id,proj_desc,proj_code,proj_date) values
                  (p_proj_id,p_proj_desc,p_proj_code,p_proj_date);
exception
when parent_not_found then
raise_application_error(-20001,'Invalid');
     END;

2 ответа

Решение

Взгляните на EXCEPTION_INIT Pragma.

DECLARE
    l_parentnotfound    exception;
    l_res               integer;
    PRAGMA EXCEPTION_INIT(l_parentnotfound, -2291);
BEGIN
    -- check if the parent key exists
    select 1 into l_res from codes where code = proj_code;
    -- if not, raise exception
    if l_res <> 1 then
        raise l_parentnotfound;
    end if;
    INSERT INTO projects (proj_id,proj_desc,proj_code,proj_date) values (p_proj_id,p_proj_desc,p_proj_code,p_proj_date);
EXCEPTION WHEN l_parentnotfound THEN
    -- handle the error
END;

Или вы можете использовать WHEN OTHERS и искать SQLCODE,

РЕДАКТИРОВАТЬ:

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

DECLARE
    l_parentnotfound    exception;
    l_res               integer;
    PRAGMA EXCEPTION_INIT(l_parentnotfound, -2291);
BEGIN
    INSERT INTO projects (proj_id,proj_desc,proj_code,proj_date) values (p_proj_id,p_proj_desc,p_proj_code,p_proj_date);
EXCEPTION WHEN l_parentnotfound THEN
    -- handle the error
END;

Но если вы хотите, чтобы можно было легко получить имя нарушенного ограничения, может быть полезно вызвать исключение вручную для каждого столбца. Также вы можете попытаться получить имя ограничения, используя USER_CONSTRAINTS а также USER_CONS_COLUMNS,

Другой способ получить имя нарушенного ограничения - это проанализировать SQLERRM сообщение об ошибке.

Пытаться

create PROCEDURE add_project(p_proj_id   project.proj_id%TYPE,
                      p_proj_desc project.proj_desc%TYPE,
                      p_proj_code project.proj_code%TYPE,
                      p_proj_date project.proj_date%TYPE) IS
BEGIN
  INSERT INTO projects
    (proj_id, proj_desc, proj_code, proj_date)
  values
    (p_proj_id, p_proj_desc, p_proj_code, p_proj_date);

  --add this   
  EXCEPTION
    WHEN OTHERS THEN
      ROLLBACK;

END;
Другие вопросы по тегам