2013-04-22 60 views
0

我想根据从gui中选择的标准动态构建查询。这里是我的Oracle包,函数返回varchar2给出错误结果

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)';这个样子,那么它失败。什么原因。

在此先感谢。

+0

好绰号! – 2013-04-22 12:39:00

+0

@EgorSkriptunoff谢谢。 :) – eatSleepCode 2013-04-22 13:14:37

回答

0

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

​​

变为:

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都将被视为单个字符串值。它必须是函数返回varchar2。但是,如果您按照Egor的建议使用绑定变量,情况也是如此。

+0

是的,我明白了这个问题,现在我从getLastName函数返回StringList,并使用查询SELECT COLUMN_VALUE FROM TABLE(TestPkg.getLastName)。 – eatSleepCode 2013-04-22 13:18:23

+0

@eatSleepCode - 很好,我会停止寻找一个如何做到这一点的例子* 8-) – 2013-04-22 13:19:41

+0

感谢它的工作现在很好。 :) – eatSleepCode 2013-04-22 13:20:18