返回varchar2的函数给出了错误的结果

时间:2013-04-22 12:14:25

标签: oracle where-clause dynamic-sql

我想根据从gui中选择的标准动态构建查询。这是我的oracle包,

CREATE OR REPLACE PACKAGE TestPkg 
AS
    g_lastnamelist VARCHAR2(50);

    FUNCTION getLastName return VARCHAR2;
    FUNCTION buildQuery(p_lastnamelist VARCHAR2);
END;

CREATE OR REPLACE PACKAGE BODY TestPkg 
AS

   FUNCTION getLastName return VARCHAR2
   IS
   BEGIN
       RETURN replace(g_lastnamelist, '''', '');
   END;

   FUNCTION buildQuery(p_lastnamelist VARCHAR2);
   IS
       m_query varchar2(1000);
   BEGIN
       g_lastnamelist := p_lastnamelist;
       m_query := 'SELECT * FROM emp WHERE last_name IN(TestPkg.getLastName)';
   END;
END;

如果我使用'SELECT * FROM emp WHERE last_name IN('||p_lastnamelist||')';,那么它会返回正确的记录,但如果我像这样使用'SELECT * FROM emp WHERE last_name IN(TestPkg.getLastName)';,则会失败。什么原因。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我假设您传入逗号分隔的引用值列表,例如p_lastnamelist'Smith','Jones',因为这是您的第一个查询可行的唯一方式,并解释了{ {1}}致电。 (如果你显示输入,输出和你得到的任何错误,它会有所帮助,所以我们不必猜测和假设)。当在查询中使用它们时,它们看起来显着不同。第一个:

replace

变为:

'SELECT * FROM emp WHERE last_name IN('||p_lastnamelist||')'

...将匹配任何具有这些姓氏的记录。但第二个:

SELECT * FROM emp WHERE last_name IN('Smith','Jones')
在您从 中删除引号后,

变为

'SELECT * FROM emp WHERE last_name IN(TestPkg.getLastName)'

...正在查找单个值,并且只有在您拥有姓氏为SELECT * FROM emp WHERE last_name IN('Smith,Jones') 的记录时才会匹配,这是不太可能的。无论Smith,Jones返回什么,都将被视为单个字符串值。必须是因为函数返回TestPkg.getLastName。但如果您使用Egor建议的绑定变量也是如此。