用于Select的过程参数(Oracle、PL/SQL)

用于Select的过程参数(Oracle、PL/SQL),sql,oracle,plsql,parameters,oracle12c,Sql,Oracle,Plsql,Parameters,Oracle12c,我有程序来执行选择: PROCEDURE Test (colValue IN VARCHAR2) IS vINS VARCHAR2(32000) := 'select * from abc.table where col10 = colValue'; BEGIN EXECUTE IMMEDIATE vINS; END; 但我不确定参数colValue是否正确用于Select 可能应该是这样:=colV

我有程序来执行选择:

PROCEDURE Test  (colValue    IN     VARCHAR2)               
IS
    vINS        VARCHAR2(32000) := 'select * from abc.table where col10 = colValue';        
BEGIN 
    EXECUTE IMMEDIATE vINS;
END;
但我不确定参数colValue是否正确用于Select


可能应该是这样:=colValue?

您可以连接变量(| |)

EDIT:正如mathguy所指出的,由于您使用的是
VARCHAR2
变量,因此需要用附加引号将其括起来。显然,对于数字变量,这是不必要的

  PROCEDURE Test  (colValue    IN     VARCHAR2)               
    IS
        vINS        VARCHAR2(32000) := 'select * from abc.table where col10 = ''' || colValue ||'''';        
    BEGIN 
        EXECUTE IMMEDIATE vINS;
    END;
事实证明,在您的情况下,使用绑定变量是非常有效的。但是,如果要动态使用表名、列名,则必须坚持连接,因为

表名和列名不能作为绑定变量传递

但是,如果未将结果存储到变量或集合中,则在
executeimmediate
中运行select语句是没有用的。 您可以使用
REF CURSOR
out变量,打印结果

  PROCEDURE Test  (colValue    IN     VARCHAR2, vINS OUT SYS_REFCURSOR)               
    IS
    BEGIN 
        OPEN vINS FOR select * from abc.table where col10 =  colValue;        
    END;


VARIABLE x REFCURSOR;
EXECUTE Test  ('Value',:x);
PRINT x;
如果您在Oracle 12c中工作,则可以使用
DBMS\u SQL。返回\u结果

   PROCEDURE Test  (colValue    IN     VARCHAR2 )             
    IS
    l_cursor   SYS_REFCURSOR;
    BEGIN 
        OPEN vINS FOR select * from abc.table where col10 =  colValue; 
        DBMS_SQL.return_result (l_cursor);

    END;

可以连接变量(| |)

EDIT:正如mathguy所指出的,由于您使用的是
VARCHAR2
变量,因此需要用附加引号将其括起来。显然,对于数字变量,这是不必要的

  PROCEDURE Test  (colValue    IN     VARCHAR2)               
    IS
        vINS        VARCHAR2(32000) := 'select * from abc.table where col10 = ''' || colValue ||'''';        
    BEGIN 
        EXECUTE IMMEDIATE vINS;
    END;
事实证明,在您的情况下,使用绑定变量是非常有效的。但是,如果要动态使用表名、列名,则必须坚持连接,因为

表名和列名不能作为绑定变量传递

但是,如果未将结果存储到变量或集合中,则在
executeimmediate
中运行select语句是没有用的。 您可以使用
REF CURSOR
out变量,打印结果

  PROCEDURE Test  (colValue    IN     VARCHAR2, vINS OUT SYS_REFCURSOR)               
    IS
    BEGIN 
        OPEN vINS FOR select * from abc.table where col10 =  colValue;        
    END;


VARIABLE x REFCURSOR;
EXECUTE Test  ('Value',:x);
PRINT x;
如果您在Oracle 12c中工作,则可以使用
DBMS\u SQL。返回\u结果

   PROCEDURE Test  (colValue    IN     VARCHAR2 )             
    IS
    l_cursor   SYS_REFCURSOR;
    BEGIN 
        OPEN vINS FOR select * from abc.table where col10 =  colValue; 
        DBMS_SQL.return_result (l_cursor);

    END;

您应该使用绑定变量,如下所示:

procedure test(colvalue in varchar2)
is
    vins long := 'select * from abc.table where col10 = :b1';
begin
    execute immediate vins using colvalue;
end;

(您可能希望实际处理结果,而不是像上面那样忽略它们,但这可能是另一个问题。根据其目的,它可能也不需要是动态的。)

您应该使用绑定变量,如下所示:

procedure test(colvalue in varchar2)
is
    vins long := 'select * from abc.table where col10 = :b1';
begin
    execute immediate vins using colvalue;
end;

(您可能希望实际对结果执行某些操作,而不是像上面那样忽略它们,但这可能是另一个问题。根据此操作的目的,它可能也不需要是动态的。)

我只想运行此过程,如果它将被插入或更新,则数据库将被更新,无需返回这不太正确-您缺少应附加在字符串
colValue
周围的单引号。您需要类似于
…=''的东西colValue | |'''''
。但是,即使你解决了这个问题,还有两个论点反对这个解决方案;请看我在威廉·罗伯逊的回答下的评论,以及@mathguy:xkcd:Hillary!我只想运行这个过程,如果它是insert或update,那么数据库将被更新,无需返回。这不太正确-您缺少了应该附加在字符串
colValue
周围的单引号。您需要类似于
…=''的东西colValue | |'''''
。但是,即使你解决了这个问题,还有两个论点反对这个解决方案;请看我在威廉·罗伯逊的回答下的评论,以及@mathguy:xkcd:Hillary@4est-此答案比您标记为“正确”的答案要好(但也更高级-可能您错过了两个答案之间的关键区别)。如果使用绑定变量编写SQL语句,如William在这里演示的,那么查询只解析一次;传入的任何输入值都将作为绑定变量传递给查询。如果将输入参数直接硬编码到SQL语句中,并使用串联(
| |
),则每次传入不同的值时,都会再次解析查询。更糟糕的是,这样做会使您面临SQL注入,这是一件非常糟糕的事情。@4est-此答案比您标记为“正确”的答案要好(但它也更高级-可能您错过了两个答案之间的关键区别)。如果使用绑定变量编写SQL语句,如William在这里演示的,那么查询只解析一次;传入的任何输入值都将作为绑定变量传递给查询。如果将输入参数直接硬编码到SQL语句中,并使用串联(
| |
),则每次传入不同的值时,都会再次解析查询。更糟糕的是,这样做会导致SQL注入,这是一件非常糟糕的事情。