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 INTO
msgstr "оператор не возвращает никакого значения, однако я всегда получу значение при выполнении этого:
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;