使用Oracle为搜索创建动态查询

时间:2018-02-13 05:52:58

标签: oracle stored-procedures filter

我需要使用基于下拉列表的过滤器在我的Oracle Database中进行搜索。因此,搜索参数总共有3个下拉列表和一个textbox。现在我想要的是。

如果用户从第一个下拉列表中选择APPLICATION,从第二个下拉列表中选择Project Name,从第三个下拉列表中选择LIKE条件。应该创建一个动态查询,并根据它应该从数据库中过滤记录。为此,我尝试的是

PROCEDURE FILTER_SEARCH_DATA
 (
 P_SEARCH_TYPE IN NVARCHAR2,
 P_PARAM_TYPE IN NVARCHAR2,
 P_OPERATOR IN NVARCHAR2,
 P_TEXTVAL IN NVARCHAR2,
 P_RETURN OUT SYS_REFCURSOR 
 )

AS
STR NVARCHAR2(400):='';
STROP NVARCHAR2(400):='';
STREX NVARCHAR2(4000):='';
BEGIN

  IF(P_OPERATOR ='LIKE') THEN
  BEGIN
   STR:=STR || '  WHERE  AM.APPLICATIONNAME ' || P_OPERATOR || '''%' || P_TEXTVAL ||'%''';
  END;
  ELSE
  BEGIN
      STR:=STR || 'WHERE AM.APPLICATIONNAME ' || P_OPERATOR  || P_TEXTVAL ;
  END;

  END IF;

  DBMS_OUTPUT.PUT_LINE('STR'|| STR);
 IF P_SEARCH_TYPE = 'APPLICATION' THEN
 DBMS_OUTPUT.PUT_LINE('START APPLICATION');
 STREX:='OPEN P_RETURN FOR SELECT AM.APPLICATIONNAME, AM.PROJECTNO, AM.VSS_FOLDER_LOC FROM APPLICATION_MASTER AM 
INNER JOIN APPLICATION_DETAILS AD
ON AM.APP_MST_ID = AD.APP_MST_ID'   || str ||';';

  DBMS_OUTPUT.PUT_LINE('STREX '|| STREX);
END IF;

 END FILTER_SEARCH_DATA;

但它并不符合我的要求。

如果您有任何与此相关的问题,请与我们联系。

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

PROCEDURE FILTER_SEARCH_DATA
 (P_SEARCH_TYPE IN NVARCHAR2,
  P_PARAM_TYPE IN NVARCHAR2,
  P_OPERATOR IN NVARCHAR2,
  P_TEXTVAL IN NVARCHAR2,
  P_RETURN OUT SYS_REFCURSOR ) AS

  STR NVARCHAR2(400):='';
  STROP NVARCHAR2(400):='';
  STREX VARCHAR2(4000):='';
  val NVARCHAR2(4000);
BEGIN
  IF (P_OPERATOR ='LIKE') THEN
      val := '%' || P_TEXTVAL ||'%';
  ELSE
      val := P_TEXTVAL;
  END IF;

  DBMS_OUTPUT.PUT_LINE('STR'|| STR);
  IF P_SEARCH_TYPE = 'APPLICATION' THEN
     DBMS_OUTPUT.PUT_LINE('START APPLICATION');
     STREX:='SELECT AM.APPLICATIONNAME, AM.PROJECTNO, AM.VSS_FOLDER_LOC 
               FROM APPLICATION_MASTER AM 
                    INNER JOIN APPLICATION_DETAILS AD
                       ON AM.APP_MST_ID = AD.APP_MST_ID 
              WHERE AM.APPLICATIONNAME ' || P_OPERATOR  || ' :PARAM';

     DBMS_OUTPUT.PUT_LINE('STREX '|| STREX);
     open P_RETURN for STREX using val;
END IF;

END FILTER_SEARCH_DATA;

此代码只是将一个字符串输出到标准输出中。你需要使用它:

:PARAM

此外,我在SQL代码中添加了参数(P_SEARCH_TYPE),它有助于提高性能并允许避免SQL注入。

另一个重要的事情:在代码中,只有'APPLICATION'等于STREX时才打开光标。您需要在其他情况下执行某些操作,否则您的过程将返回关闭的光标。

<强> UPD
VARCHAR2应该是NVARCHAR2,而不是{{1}}。