Oracle SQL - 动态查询的替代方案

时间:2014-03-05 16:57:06

标签: sql oracle plsql

我有一个使用动态查询的程序(见下文)。我想在不使用动态查询的情况下重写此过程。我如何写下面的条件?

PROCEDURE DemoProcedure(p_firstname  IN VARCHAR2,
                       p_lastname   IN VARCHAR2,
                       p_phone        IN VARCHAR2
                       o_Cursor     OUT t_Cursor) IS

SQLString VARCHAR2(4000);

BEGIN

    SQLString := 
        'SELECT * FROM 
        SCHEMA.TABLENAME_a A
        INNER JOIN SCHEMA.TABLENAME_b B
        ON A.ID = B.ID
        WHERE 
        A.TYPE = 1  ';

    IF p_firstname IS NOT NULL THEN
        SQLString := SQLString || ' and UPPER(A.FIRST_NAME) like UPPER( ''' || p_firstname || ''')';
    END IF;

    IF p_lastname IS NOT NULL THEN
        SQLString := SQLString || ' and UPPER(A.LAST_NAME) like UPPER( ''' || p_lastname || ''')';
    END IF;

    IF p_phone IS NOT NULL THEN
        SQLString := SQLString || ' and UPPER(A.PHONE) = ''' ||
                            p_phone || '''';
    END IF;

        SQLString := SQLString || ' order by  a.id ';

        OPEN o_Cursor FOR SQLString;

END DemoProcedure;

2 个答案:

答案 0 :(得分:3)

看起来你只想要

OPEN o_cursor 
 FOR SELECT ...
      WHERE A.TYPE = 1
        AND (p_firstname IS NULL or upper(a.first_name) = upper(p_firstname))
        AND (p_lastname  IS NULL or upper(a.last_name)  = upper(p_lastname))
        AND (p_phone     IS NULL or upper(a.phone)      = p_phone)
      ORDER BY a.id

我不确定你为什么要打扰电话号码的上限 - 你是否在电话号码中有字符数据?

答案 1 :(得分:3)

编写与@JustinCave建议相同的SQL的不同方式 -

OPEN o_cursor 
 FOR SELECT ...
      WHERE A.TYPE = 1
        AND upper(a.first_name) = nvl(upper(p_firstname), upper(a.first_name))
        AND upper(a.last_name)  = nvl(upper(p_lastname),upper(a.last_name))
        AND upper(a.phone)      = nvl(p_phone,upper(a.phone))
      ORDER BY a.id