【问题标题】:Function the return number by using dynamic sql使用动态 sql 函数返回数字
【发布时间】:2016-05-06 21:21:19
【问题描述】:

我想创建一个返回 data_byte 的函数,稍后我可以在 rpad 函数中使用它。这是我提出的上一个问题,我得到了有用的答复。 function that return data type that can be used in SQL(oracle)

这是我添加的当前功能代码:

create or replace FUNCTION get_data(tab_name in varchar2, column_name in varchar2) return number
is
  return_val NUMBER;
  str varchar2(1000) := 'select data_length from user_tab_columns where table_name = ' || ''''||tab_name||''''|| ' and column_name = ' || '''' || column_name || '''';
begin
 dbms_output.put_line(str);
  execute immediate(str);
  return(return_val);
end;
/
select get_data('EMPLOYEES', 'SALARY') from dual;

我牢记函数需要返回类型。成功编译函数后,我尝试从dual中选择它,我得到了NULL值。我希望它为我返回 22,但我只得到了空值。那是因为我的返回类型错误吗?或者我应该如何解决它。

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    您的问题是 return_val 没有被填充。例如下面的代码有效:

    create or replace FUNCTION get_data(tab_name in varchar2, column_name in varchar2) return number
    is
      return_val NUMBER;
      str varchar2(1000) := 'select data_length from user_tab_columns where table_name = ' || ''''||tab_name||''''|| ' and column_name = ' || '''' || column_name || '''';
    begin
      dbms_output.put_line(str);
      execute immediate(str) INTO return_val;
      return(return_val);
    end;
    

    【讨论】:

    • 嗨 Chrisrs2292,我可以知道为什么必须在立即执行后写入“INTO”吗?原因和SELECT INTO 语句一样吗?我试图找到“INTO”理论,以便更好地理解它,但没有结果。如果这不打扰你,你能解释一下原因吗?对不起,如果我问愚蠢的问题。感谢您的帮助。
    • 我遇到了一个新问题。当我选择数据类型为“NUMBER”的列时,它返回 22。但是当我选择其他数据类型时,它返回定义的确切数字。例如,数据类型为 number(2,2) 或 number(8,2) 的列,它总是返回 22。
    • 没有“INTO”,Oracle 不知道将查询返回的值放在哪里。就像你说的,这与“Select Into”基本相同,你可以在这里阅读:docs.oracle.com/cd/B19306_01/appdev.102/b14261/… 至于为什么你得到 22,这基本上归结为数字在数据库中的存储方式。您可以在这里阅读更多相关信息:asktom.oracle.com/pls/asktom/… 如果您想返回“8,2”,您需要来自 user_tab_columns 的 Data_Precision 和 Data_Scale 列
    【解决方案2】:

    你应该:

    execute immediate str into return_val;
    return return_val;
    

    【讨论】:

      【解决方案3】:

      在这种情况下,您不需要动态 sql。只需像这样使用 CURSOR 或 SELECT INTO 子句:

      create or replace FUNCTION get_data(tab_name in varchar2, column_name in varchar2) return number is
        return_val NUMBER;
        cursor c_data(cp_table Varchar2, cp_column Varchar2) is
          select data_length
            from user_tab_columns
            where table_name = cp_table and
                  column_name = cp_column;
      begin
      
        open c_data(tab_name, column_name);
        fetch c_data into return_val;
        close c_data;
      
        return(return_val);
      end;
      

      【讨论】:

      • “当你使用动态 SQl 时,你不能在 SELECT 语句中使用你的函数”。你确定吗?
      • 我是 - 直到我做了一个测试:) 在早期版本中,由于潜在的副作用,这是不可能的。现在Oracle显然在运行时检查副作用,所以select是可能的,其他DML不行。我会更正我的答案。谢谢!
      【解决方案4】:
      create or replace FUNCTION get_data(tab_name in varchar2, column_name in varchar2) return number
      is
        return_val NUMBER;
      begin
      select data_length into return_val from user_tab_columns where table_name = tab_name and column_name = column_name
      and rownum<2;
      return return_val;
      end;
      /  
      

      【讨论】:

        猜你喜欢
        • 2018-03-21
        • 1970-01-01
        • 2021-10-21
        • 2010-11-04
        • 2017-06-27
        • 1970-01-01
        • 2017-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多