ORA-01403: 找不到数据 为什么?

ORA-01403: No Data found WHY?

我已声明以下程序:

 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”语句没有 return 任何值,通常会抛出此异常,但是当我执行此语句时,我总是会得到一个值:

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

当我执行上面的代码时,结果是 "N" 或 "Y"。所以我总是得到一个结果。不知道为什么会抛出这个异常

您正在将 v_defaultValue 参数传递给列名。

将程序更改为

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

您的通话包含尾随 space:

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

所以 proc 抛出找不到数据因为 'COLUMN_NAME ' != 'COLUMN_NAME'

使用upper(trim(v_cName))防止拼写错误导致错误。应用于所有参数。

SELECT .... INTO 之前,您必须确保 select 有所作为。因为看你是什么用户,给什么参数,你的table.

里面可能没有数据

一个简单的方法是在 SELECT:

之前的开头有一个 COUNT
 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;