动态SQL选择变量

时间:2017-09-29 13:27:37

标签: sql oracle plsql dynamic-sql

我正在尝试创建一个将在表名中使用的函数,获取该表名并将其转换为列名,因为这是表的设计。该函数还接受表的PK代码,并使用它来构造一个Dynamic语句,该语句将选择值返回变量。

我收到的错误如下:

SP2-0552:绑定变量" LOC_CODE_TAB"没有宣布。

所以我的主要问题是何时使用派生值作为绑定变量,何时不使用。

以下是我正在尝试的示例:

DECLARE
    loc_stmt      VARCHAR2(200);
    loc_return    VARCHAR2(30) := null;
    loc_code_tab  VARCHAR2(30);
    P_TABLE_NAME VARCHAR2(100) := 'BILLG_FRQNCY_TYPE';
    P_CODE      NUMBER := 1;
BEGIN
    loc_code_tab := SUBSTR(P_TABLE_NAME,1,LENGTH(P_TABLE_NAME)-3);

    loc_stmt := 
        'SELECT ' || :loc_code_tab || '_DESC' ||
         ' INTO ' || loc_return ||  
         ' FROM ' || :loc_code_tab || 
        ' WHERE ' || P_TABLE_NAME || ' = ' || :P_CODE;

    EXECUTE IMMEDIATE loc_stmt
        INTO loc_return
        USING IN loc_code_tab, IN loc_code_tab, IN P_CODE;
    DBMS_OUTPUT.PUT_LINE(loc_return);
END;
/

2 个答案:

答案 0 :(得分:2)

您无法在动态查询中将placeholders用于表列。但是,您可以使用concatenate来实现您的要求。见下文:

DECLARE
   loc_stmt       VARCHAR2 (200);
   loc_return     VARCHAR2 (30) := NULL;
   loc_code_tab   VARCHAR2 (30);
   P_TABLE_NAME   VARCHAR2 (100) := 'BILLG_FRQNCY_TYPE';
   P_CODE         NUMBER := 1;
BEGIN
   loc_code_tab := SUBSTR (P_TABLE_NAME, 1, LENGTH (P_TABLE_NAME) - 3);

   loc_stmt :=
         'SELECT  '
      || loc_code_tab
      || '_DESC'
      || ' FROM '
      || loc_code_tab
      || ' WHERE '
      || P_TABLE_NAME
      || ' = '
      || P_CODE;

   EXECUTE IMMEDIATE loc_stmt  INTO loc_return ;

   DBMS_OUTPUT.PUT_LINE (loc_return);
END;
/

答案 1 :(得分:1)

从可变的名称中删除:,然后进入正确执行的适当位置。

DECLARE
    loc_stmt      VARCHAR2(200);
    loc_return    VARCHAR2(30) := null;
    loc_code_tab  VARCHAR2(30);
    P_TABLE_NAME VARCHAR2(100) := 'BILLG_FRQNCY_TYPE';
    P_CODE      NUMBER := 1;
BEGIN
    loc_code_tab := SUBSTR(P_TABLE_NAME,1,LENGTH(P_TABLE_NAME)-3);

    loc_stmt := 
        'SELECT ' || loc_code_tab || '_DESC' ||
         ' FROM ' || loc_code_tab || 
        ' WHERE ' || P_TABLE_NAME || ' = ' || P_CODE;

    EXECUTE IMMEDIATE loc_stmt
        INTO loc_return;
    DBMS_OUTPUT.PUT_LINE(loc_return);
END;
/