如何使用动态用户输入在 plsql 中使用函数/过程创建表

Posted

技术标签:

【中文标题】如何使用动态用户输入在 plsql 中使用函数/过程创建表【英文标题】:How to create a table using a function/procedure in plsql using dynamic user input 【发布时间】:2017-11-18 10:03:39 【问题描述】:

如何在 plsql 中使用函数/过程创建表,以便将表名作为动态变量并使用提供的参数创建该表? A)我试过这个:

CREATE OR REPLACE PROCEDURE CREATE_TABLE IS
UN VARCHAR2(20) :=&TABLE_NAME;

BEGIN
    CREATE TABLE UN(CUSTOMER_ID NUMBER,ORDER_DATE VARCHAR2(20),ORDER_MODE VARCHAR2(20),ORDER_STATUS NUMBER,SALES_REP_ID NUMBER,ORDER_TOTAL NUMBER,
    PROMOTION_ID CHAR,ERROR_MESSAGE VARCHAR2(30),RECORD_STATUS CHAR);
    end;

    insert into UN(select distinct CUSTOMER_ID,TO_CHAR(TO_TIMESTAMP(ORDER_DATE),'DD-MM-YYYY'),UPPER(ORDER_MODE),UPPER(ORDER_STATUS),SALES_REP_ID,ORDER_TOTAL,PROMOTION_ID,ERROR_MESSAGE,RECORD_STATUS 
    FROM LIKHITH where ORDER_TOTAL >0 AND ORDER_TOTAL NOT LIKE '%.%');
    IF COUNT(CUSTOMER_ID)=9 THEN 
    (
    UPDATE LIKHITH SET (RECORD_STATUS='E' AND ERROR_MESSAGE='ERR') WHERE (ORDER_TOTAL<0 OR ORDER_TOTAL NOT LIKE '%.%');
    UPDATE LIKHITH SET RECORD_STATUS='P' WHERE (ORDER_TOTAL<0 AND ORDER_TOTAL NOT LIKE '%.%');
    UPDATE UN SET RECORD_STATUS='P';
    )
    END IF;
   )
END;
/

【问题讨论】:

即使 PL/SQL 有 create table(它没有),这也永远无法编译,因为表 UN 无法在编译时解析。 &amp;TABLE_NAME 但是将在编译时解析(假设这是由支持替换变量并使用 &amp; 字符的应用程序运行的),这可能不是您想要的。 感谢您的回复,我明白了您所说的并修改了代码,现在终于可以使用了。 【参考方案1】:

您需要使用动态 SQL。您的代码中有许多多余的括号,这不是必需的。

这行IF COUNT(CUSTOMER_ID)=9 也没有任何意义。您应该从表中进行选择并进行比较。

CREATE OR REPLACE PROCEDURE CREATE_TABLE 
                                        (  un VARCHAR2) 
IS
        v_count NUMBER;
BEGIN
        EXECUTE IMMEDIATE 'CREATE TABLE '|| 
        UN                               || 
        '                
(                        
CUSTOMER_ID   NUMBER,                        
ORDER_DATE    VARCHAR2(20),                        
ORDER_MODE    VARCHAR2(20),                        
ORDER_STATUS  NUMBER,                        
SALES_REP_ID  NUMBER,                        
ORDER_TOTAL   NUMBER,                        
PROMOTION_ID  CHAR,                        
ERROR_MESSAGE VARCHAR2(30),                        
RECORD_STATUS CHAR                
)';
        EXECUTE IMMEDIATE 'insert into '|| 
        UN                              || 
        '        
select distinct                
CUSTOMER_ID,                
TO_CHAR(TO_TIMESTAMP(ORDER_DATE),''DD-MM-YYYY''),                
UPPER(ORDER_MODE),                
UPPER(ORDER_STATUS),                
SALES_REP_ID,                
ORDER_TOTAL,                
PROMOTION_ID,                
ERROR_MESSAGE,                
RECORD_STATUS        
FROM                
LIKHITH        
where   ORDER_TOTAL  >0                
AND ORDER_TOTAL NOT LIKE ''%.%''' ;
        EXECUTE IMMEDIATE 'SELECT COUNT(CUSTOMER_ID) FROM ' || 
        UN INTO v_count;
        IF v_count = 9 THEN
                UPDATE
                        LIKHITH 
                SET     RECORD_STATUS         ='E' ,
                        ERROR_MESSAGE         ='ERR'
                WHERE   ORDER_TOTAL           <0
                        OR ORDER_TOTAL NOT LIKE '%.%';

        ELSE
                UPDATE
                        LIKHITH
                SET     RECORD_STATUS          ='P'
                WHERE   ORDER_TOTAL            <0
                        AND ORDER_TOTAL NOT LIKE '%.%';

                EXECUTE IMMEDIATE 'UPDATE '|| 
                UN                         || 
                ' SET RECORD_STATUS=''P''';
        END IF;
END;
/

不要在编译期间传递表名,就像你尝试的那样。在执行期间传递它,如下所示。

EXEC CREATE_TABLE('&table_name');

【讨论】:

这个答案看起来不错,我试过奏效了。感谢您的输入,该可执行文件现在仅动态传递。

以上是关于如何使用动态用户输入在 plsql 中使用函数/过程创建表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PLSQL 中获取 livesql.oracle.com 中的用户输入

在plsql中编写函数

plsql使用教程

Oracle APEX 交互式网格:如何使用 PLSQL 访问内容?

plsql 在 datagrip ide 中使用

『ORACLE』 PLSQL动态游标的使用(11g)