Stored procedures 在用户定义函数中执行立即数-在内部查询中调用

Stored procedures 在用户定义函数中执行立即数-在内部查询中调用,stored-procedures,plsql,oracle11g,Stored Procedures,Plsql,Oracle11g,我正在使用存储过程从oracle数据库中获取记录。此过程根据提供的搜索输入返回分页记录,以构建动态SQL查询。输出“STATUS”列是从用户定义的函数“GET_STATUS_FOR_ME”派生的。根据计算每个记录的实际状态,将一些派生列传递到此函数 一切正常,但不提供状态作为输入搜索条件。当提供状态时,它会给我以下错误 ORA-06535: statement string in EXECUTE IMMEDIATE is NULL or 0 length ORA-06512: at "p

我正在使用存储过程从oracle数据库中获取记录。此过程根据提供的搜索输入返回分页记录,以构建动态SQL查询。输出“STATUS”列是从用户定义的函数“GET_STATUS_FOR_ME”派生的。根据计算每个记录的实际状态,将一些派生列传递到此函数

一切正常,但不提供状态作为输入搜索条件。当提供状态时,它会给我以下错误

    ORA-06535: statement string in EXECUTE IMMEDIATE is NULL or 0 length
ORA-06512: at "pkg_search", line 15
06535. 00000 -  "statement string in %s is NULL or 0 length"
*Cause:    The program attempted to use a dynamic statement string that
           was either NULL or 0 length.
*Action:   Check the program logic and ensure that the dynamic statement
           string is properly initialized.
我的用户定义功能如下:

FUNCTION GET_STATUS_FOR_ME(
    RECORDID     IN NUMBER,
    ASSIGNEDTO   IN NUMBER,
    LOCATIONID   IN NUMBER,
    TEMPUSERID   IN NUMBER,
    ACTUALSTATUS IN VARCHAR2)
  RETURN VARCHAR2
AS
  O_STATUS   VARCHAR2(200 BYTE);
  TEMP_QUERY VARCHAR2(200 BYTE);
  I_COUNT    NUMBER;
BEGIN
  IF LOCATIONID IS NOT NULL AND TEMPUSERID IS NULL THEN
    TEMP_QUERY  := 'SELECT COUNT(*) FROM MY_TABLE WHERE COUNTRYIF = ' || TO_CHAR(LOCATIONID);
    EXECUTE IMMEDIATE TEMP_QUERY INTO I_COUNT;
  END IF;

  . . . Other FUNCTION logic here. . .

    RETURN O_STATUS;
  END GET_STATUS_FOR_ME;
我调用此函数的过程如下所示。正在从内部查询调用此函数

  PROCEDURE SEARCH_RESULT_PROC(
      I_LOGGEDINUSERID  IN NUMBER,
      I_CREATEDFROMDATE IN DATE,
      I_CREATEDTODATE   IN DATE,
      I_STATUS          IN VARCHAR2,
      I_COUNTRYID       IN NUMBER,
      I_LANGUAGEID      IN NUMBER,
      I_OFFSET          IN NUMBER,
      I_LIMIT           IN NUMBER,
      I_ORDRBY          IN VARCHAR2,
      I_SORTBY          IN VARCHAR2,
      O_COUNT OUT NUMBER,
      REF_CUS_RESULTS OUT SYS_REFCURSOR)
  AS
    PAG_END_ROW           NUMBER;
    STC_SQL_PART          VARCHAR2(9999 BYTE);
    DYNMC_SQL_CLAUSE_PART VARCHAR2(9999 BYTE);
  BEGIN
    PAG_END_ROW  := I_OFFSET + I_LIMIT - 1;
    STC_SQL_PART := 'select ID, REOCRDSTATUS, 
(CASE          
some logic here       
END) LOCATIONID, 
(CASE          
some logic here       
END) USERID from MY_TABLE MTABLE';

    . . Other Logic TO build dynamic WHERE clause depending ON inputs provided. . .

    IF I_DOCSTATUS          IS NOT NULL THEN
      DYNMC_SQL_CLAUSE_PART := DYNMC_SQL_CLAUSE_PART || ' AND UPPER(TEMPDATA.STATUS)  = UPPER(''' || I_STATUS || ''')';
    END IF;
    FINAL_QUERY := 'SELECT ODATA.EID,  
ODATA.TITLE,  
ODATA.TYPE,   
pkg_search.GET_STATUS_FOR_ME(ID,' || I_LOGGEDINUSERID || ',ODATA.LOCATIONID,ODATA.USERID,ODATA.REOCRDSTATUS) STATUS
FROM (SELECT ROWNUM RNUM , TEMP.* FROM ( ' || STC_SQL_PART || DYNMC_SQL_CLAUSE_PART || ' )TEMP WHERE ROWNUM <= ' || TO_CHAR(PAG_END_ROW) ||' ) ODATA WHERE ODATA.RNUM >= '|| TO_CHAR( I_OFFSET) ;
    OPEN REF_CUS_RESULTS FOR FINAL_QUERY;
  END SEARCH_RESULT_PROC;
过程搜索\u结果\u过程(
I_LOGGEDINUSERID的编号,
我在日期中创建了FromDate,
我在日期上创建了日期,
I_在VARCHAR2的身份,
我的国家号是多少,
我的语言编号为,
I_在数量上有偏移,
我的数量有限,
我在瓦查尔的奥德比,
我在瓦查尔很糟糕,
你数一数,
REF_CUS_结果输出系统(REF光标)
作为
PAG_END_行编号;
STC_SQL_部分VARCHAR2(9999字节);
DYNMC_SQL_子句_部分VARCHAR2(9999字节);
开始
PAG_END_行:=I_偏移量+I_限制-1;
STC_SQL_部分:='选择ID,REOCRDSTATUS,
(案例
这里有些逻辑
结束)位置ID,
(案例
这里有些逻辑
结束)来自MY_表MTABLE'的用户ID;
. . 根据提供的输入构建动态WHERE子句的其他逻辑。
如果I_DOCSTATUS不为空,则
DYNMC|U SQL|U子句|U PART:=DYNMC|U SQL|U子句|U PART|||和UPPER(TEMPDATA.STATUS)=UPPER(“”’| | |’);
如果结束;
最终查询:='选择ODATA.EID,
小田,
ODATA.TYPE,
pkg|u search.GET_STATUS_FOR_ME(ID,“| | I| LOGGEDINUSERID | | |”,ODATA.LOCATIONID,ODATA.USERID,ODATA.REOCRDSTATUS)状态
FROM(选择ROWNUM RNUM,TEMP.*FROM(“| | STC| u SQL_PART | | | DYNMC_SQL_子句| | |”)TEMP,其中ROWNUM=”| | TO_CHAR(I|u OFFSET);
打开REF\u CUS\u结果进行最终查询;
结束搜索\u结果\u过程;

hi,哪一行是pkg_搜索的第15行?在阅读了您的代码后,我想您的过程可能不会那么复杂,并且可以用作带有bind参数的常规SQL查询。您可以使用
ROWNUM
ROW_NUMBER()
窗口函数(可能
使用
子句用法)进行分页,可以使用simple
NVL()绑定参数
CASE
语句,您就不会在SGA中充斥使用动态SQL创建的几乎每一个查询的计划。您甚至可以使用一点
CASE
语句,根据绑定参数创建
订单。使用动态生成查询维护代码是一场噩梦。