动态 SQL 到 select 成一个变量

Dynamic SQL to select into a variable

我正在尝试创建一个将采用 table 名称的函数,采用该 table 名称并将其转换为列名称,因为这是 [=26= 的设计].该函数还接收一个代码,table 的 PK,并使用它来构造一个 Dynamic 语句,该语句将 select 值转换为变量 return 它。

我收到如下错误:

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;
/

您不能在动态查询中对 table 列使用 placeholders。但是,您可以使用连接来实现您的要求。见下文:

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;
/

从变量名中删除:并移动到立即执行的适当位置。

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;
/