ORA-01403: Данные не найдены ПОЧЕМУ?

Я объявил следующую процедуру:

 CREATE OR REPLACE PROCEDURE MODIFY_NOT_NULL(
      v_tbName       IN VARCHAR2,
      v_cName        IN VARCHAR2,
      v_defaultValue IN VARCHAR2 )
   IS
      v_is_null VARCHAR2(1);
   BEGIN

      SELECT nullable INTO v_is_null 
      FROM USER_TAB_COLUMNS 
      WHERE TABLE_NAME = v_tbName 
      AND COLUMN_NAME  = v_cName;

      IF  v_is_null   = 'Y' THEN
          EXECUTE IMMEDIATE ('ALTER TABLE ' || v_tbName 
               || ' MODIFY (' || v_cName 
               || ' DEFAULT ' || v_defaultValue 
               || '  NOT NULL )');
      END IF;
   END;

Однако, когда я выполняю свой код:

BEGIN
   modify_not_null('TABLE_NAME', 'COLUMN_NAME ' ,'0');
END;
/ 

Я получаю

"ORA-01403: No Data Found"

Это исключение обычно выдается, еслиSELECT INTOmsgstr "оператор не возвращает никакого значения, однако я всегда получу значение при выполнении этого:

Select nullable 
from USER_TAB_COLUMNS 
WHERE table_name = 'TABLE_NAME' 
AND column_name  = 'COLUMN_NAME';

Когда я выполняю код выше, я получаю "N" или "Y" в результате. Так что я всегда получаю результат. Я не знаю, почему это исключение

4 ответа

Решение

Ваш звонок содержит пробел:

modify_not_null('TABLE_NAME', 'COLUMN_NAME ' ,'0');
                                          ^

Так что proc не выдает никаких данных, потому что 'COLUMN_NAME ' != 'COLUMN_NAME'

использование upper(trim(v_cName)) чтобы предотвратить опечатки, вызывающие ошибки. Применить по всем параметрам.

Вы передаете параметр v_defaultValue в имя столбца.

Изменить процедуру на

SELECT nullable INTO v_is_null 
FROM USER_TAB_COLUMNS 
WHERE TABLE_NAME = v_tbName AND COLUMN_NAME  = v_cName ;

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

Простой способ будет иметь COUNT в начале до SELECT:

 CREATE OR REPLACE PROCEDURE MODIFY_NOT_NULL(
      v_tbName       IN VARCHAR2,
      v_cName        IN VARCHAR2,
      v_defaultValue IN VARCHAR2 )
   IS
      v_is_null VARCHAR2(1);
      v_count number;
   BEGIN
      -- added select count
      SELECT count(1) INTO v_count FROM USER_TAB_COLUMNS WHERE TABLE_NAME = trim(v_tbName) AND COLUMN_NAME  = trim(v_cName);
      -- added if v_count=1
      if v_count = 1 then
        SELECT nullable INTO v_is_null FROM USER_TAB_COLUMNS WHERE TABLE_NAME = trim(v_tbName) AND COLUMN_NAME  = trim(v_cName);

        IF  v_is_null   = 'Y' THEN
         EXECUTE IMMEDIATE ('ALTER TABLE ' || v_tbName || ' MODIFY (' || v_cName || ' DEFAULT ' || v_defaultValue || '  NOT NULL )');
        END IF;
      -- added
      end if;
   END;
/

Поделитесь и наслаждайтесь

Оставаться стильным:)

create or replace procedure modify_not_null(v_tbName       in varchar2,
                                            v_cName        in varchar2,
                                            v_defaultValue in varchar2) is
  cursor c_tbl(cp_tbname in varchar2, 
               cp_cname in varchar2) is
    select nullable
      from user_tab_columns
     where table_name  = upper(cp_tbname)
       and column_name = upper(cp_cname);

  l_tbl c_tbl%rowtype;
begin

  open c_tbl(cp_tbname => v_tbName,
             cp_cname => v_cName);
  fetch c_tbl into l_tbl;
  close c_tbl;

  if l_tbl.nullable = 'Y' then
    execute immediate 'alter table ' || v_tbName || ' modify (' || v_cName ||
                      ' default ' || v_defaultValue  || '  not null )';
  end if;
exception
  when others then
    raise_application_error(-20000, dbms_utility.format_error_stack);
end modify_not_null;
Другие вопросы по тегам