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

时间:2017-01-20 10:24:38

标签: oracle plsql database-metadata execute-immediate

我已宣布以下程序:

 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”。所以我总能得到一个结果。我不知道为什么抛出这个异常

4 个答案:

答案 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;