【问题标题】:Oracle Create FunctionOracle 创建函数
【发布时间】:2016-08-09 19:53:12
【问题描述】:

我尝试创建一个 Oracle 函数,其中表名、列名和字符串是动态参数:

CREATE OR REPLACE FUNCTION MYSCHEMA.myFunctionName( 
  tableName in nvarchar2,
  columnName in nvarchar2,
  whereStr in nvarchar2)
RETURN nvarchar2

IS nActive nvarchar2(2000);

BEGIN
  declare 
  querystr nvarchar2(2000) ;
  result nvarchar2(2000);
  begin
    querystr :='
    select  listagg('+columnName+','+','+') within group (order by '+columnName+')
    from '+tableName+' where  1 = 1 '+whereStr+';';
    EXECUTE IMMEDIATE querystr
    INTO result;
       nActive := result;
          RETURN ( nActive );
  end;
END ;
/

但它给了我错误“警告:已编译但存在编译错误”。

我做错了什么?

【问题讨论】:

  • 使用show errors 或查询user_errors 视图来查看实际的编译错误。 (SQL Developer 也有一个显示它们的窗格)。您需要查看动态字符串中的非转义引号和连接字符(|| 不是 +);但为什么你的 listagg 有三个参数?

标签: oracle plsql dynamic-sql


【解决方案1】:
  1. 对于Oracle 中的连接字符串,使用|| 而不是+
  2. ; 不需要在execute immediate 查询字符串的末尾
  3. 您需要使用'' 转义'

...正如@Aleksej 所说

  1. Execute immediate需要CHAR or VARCHAR2中的查询字符串;
  2. listagg 返回 rawVARCHAR2

CREATE OR REPLACE FUNCTION MYSCHEMA.myFunctionName( 
  tableName in varchar2,
  columnName in varchar2,
  whereStr in varchar2)
RETURN varchar2
BEGIN
  declare 
  querystr varchar2(2000) ;
  result varchar2(2000);
  begin
    querystr :='
    select  listagg('|| columnName || ', '','') within group (order by ' ||columnName ||')
    from ' || tableName || ' where  1 = 1 ' || whereStr;
    EXECUTE IMMEDIATE querystr INTO result;
    return result;
  end;
END ;
/

【讨论】:

  • 谢谢哥们...真正的查询是 CREATE OR REPLACE FUNCTION name(tableName in varchar2, columnName in varchar2, whereStr in varchar2) RETURN varchar2 IS nActive varchar2(2000); BEGIN 声明 querystr varchar2(2000) ;结果 VARCHAR2(2000); begin querystr :=' select listagg('|| columnName || ', '','') in group (order by ' ||columnName ||') from ' ||表名 || ' 其中 1 = 1 ' ||其中Str; EXECUTE IMMEDIATE querystr INTO 结果; nActive := 结果;返回(nActive);结尾;结尾 ; /
【解决方案2】:

考虑到这一点,您需要更改变量的类型

  • "如果度量列为 RAW,则返回数据类型为 RAW;否则返回值为 VARCHAR2" (documentation)
  • EXECUTE 需要一个 VARCHAR2:“它必须是 CHAR 或 VARCHAR2 类型,而不是 NCHAR 或 NVARCHAR2”

所以:

declare 
  querystr varchar2(2000) ;
  result VARCHAR2(32767);
begin
  ...

【讨论】:

    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 2020-01-25
    • 2022-01-25
    • 2021-01-21
    • 2014-12-02
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多