2017-09-25 110 views
0

下面是一个例子查询,我想我的程序产生如何通过字符串值作为参数PLSQL过程

select * 
    from Registration 
    where Loc_ID = 6 
    AND CROP_ID = 163 
    AND REG_NAME = 'Apiro MX'; 

REG_NAMEvarchar2()

我已创建了一个程序,在这里我想执行一个查询类似下面

query := 'select REG_ID from Registration where loc_id = ' || 
      countryid || ' AND Crop_id = ' || cropid || 
      ' AND Reg_name = '|| ''' || productid || ''' || '; 

我得到的REG_NAME部分错误,它正在productid as " || productid ||"

你能否帮我准确的查询一下。

+1

你为什么要为该查询使用动态SQL? (如果你有一个真正的理由,为什么你不使用绑定变量?) –

+0

我们不能使用动态sql做到这一点,如果可能的话,请你纠正我的查询。 –

+0

当然,你可以通过转义你正在使用的引号,或者(很多)最好使用绑定变量;但你为什么要?它效率较低,难以维护。 –

回答

1

你并不需要使用动态SQL:

CREATE PROCEDURE get_registration (
    i_countryid IN REGISTRATION.LOC_ID%TYPE, 
    i_crop_id IN REGISTRATION.CROP_ID%TYPE, 
    i_reg_name IN REGISTRATION.REG_NAME%TYPE, 
    o_cursor OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
    OPEN o_cursor FOR 
    SELECT * 
    FROM Registration 
    WHERE Loc_ID = i_countryid 
    AND CROP_ID = i_crop_id 
    AND REG_NAME = i_reg_name; 
END; 
/

如果您确实需要动态SQL(但你几乎总是可以做到无):

CREATE PROCEDURE get_registration (
    i_countryid IN REGISTRATION.LOC_ID%TYPE, 
    i_crop_id IN REGISTRATION.CROP_ID%TYPE, 
    i_reg_name IN REGISTRATION.REG_NAME%TYPE, 
    o_cursor OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
    OPEN o_cursor 
    FOR 'SELECT * 
     FROM Registration 
     WHERE Loc_ID = :i 
     AND CROP_ID = :j 
     AND REG_NAME = :k' 
    USING i_countryid, i_crop_id, i_reg_name; 
END; 
/
+0

,可以吗?你能纠正这个问题吗? –

+0

原始查询是“正确的”,但是,我可以为您提供一个替代方案。 – MT0

-1

在PLSQL可以通过增加另一个来逃避报价,因此, 您应该在productid周围放置双引号。 试着这么做:

query := 'select REG_ID from Registration where loc_id = ' || 
     countryid || ' AND Crop_id = ' || cropid || 
     ' AND Reg_name = '|| '''' || productid || '''' || '; 

或者不使用动态SQL和尝试创建存储过程 (检查链接的指令)。 http://plsql-tutorial.com/plsql-procedures.htm

+1

这是一个坏主意[XKCD](https://xkcd.com/327/) - 如果你不使用绑定变量,那么用户可以做一些意想不到的事情,比如将'productid'作为'Apiro MX'和EXISTS(SELECT 1 FROM your_password_table WHERE passwordhash ='123456')AND'1'='1'。 – MT0