我已宣布以下程序:
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
”语句没有返回任何值,通常会抛出此异常,但是执行此操作时,我总是会得到一个值:
Select nullable
from USER_TAB_COLUMNS
WHERE table_name = 'TABLE_NAME'
AND column_name = 'COLUMN_NAME';
当我执行上面的代码时,我得到“N”或“Y”。所以我总能得到一个结果。我不知道为什么抛出这个异常
答案 0 :(得分:4)
您的通话包含一个尾随空格:
modify_not_null('TABLE_NAME', 'COLUMN_NAME ' ,'0');
^
所以proc不会发现因为'COLUMN_NAME ' != 'COLUMN_NAME'
使用upper(trim(v_cName))
来防止拼写错误导致错误。适用于所有参数。
答案 1 :(得分:1)
您正在将v_defaultValue参数传递给列名。
将程序更改为
chmod +x HideMarker
答案 2 :(得分:0)
在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;
/
分享并享受
答案 3 :(得分:-1)
保持优雅:)
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;