PL/SQL 中的 DDL 语句?

Posted

技术标签:

【中文标题】PL/SQL 中的 DDL 语句?【英文标题】:DDL statements in PL/SQL? 【发布时间】:2012-06-30 09:08:46 【问题描述】:

我正在尝试下面的代码在PL/SQL 中创建一个表:

DECLARE
    V_NAME VARCHAR2(20);
BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE TEMP(NAME VARCHAR(20))';
    EXECUTE IMMEDIATE 'INSERT INTO TEMP VALUES(''XYZ'')';
    SELECT NAME INTO V_NAME FROM TEMP;
END;
/

SELECT 语句失败并出现以下错误:

PL/SQL: ORA-00942: table or view does not exist

是否可以CREATE, INSERT and SELECT 一个接一个地在一个 PL/SQL 块中?

【问题讨论】:

为什么要使用动态sql?它更慢更危险。并插入作品? 这是个坏主意。它是其他一些 RDBMS 风格(例如 SQL Server)中的常见构造,但 Oracle 提供了更好的方法。欲了解更多信息,请阅读我的这个旧答案:***.com/a/1193443/146325 【参考方案1】:

我假设您正在执行以下操作:

declare
   v_temp varchar2(20);
begin
   execute immediate 'create table temp(name varchar(20))';
   execute immediate 'insert into temp values(''XYZ'')';

   select name into v_name from temp;
end;

在编译时,表TEMP不存在。它还没有被创建。由于它不存在,因此您无法从中进行选择;因此,您还必须动态执行 SELECT。尽管您可以使用returning into 语法,但在这种特定 情况下实际上不需要执行 SELECT。

declare
   v_temp varchar2(20)
begin
   execute immediate 'create table temp(name varchar2(20))';
   execute immediate 'insert into temp 
                      values(''XYZ'')
                      returning name into :1'
                returning into v_temp;
end;

但是,需要动态创建表通常表明架构设计不当。应该没有必要。

我可以推荐René Nyffenegger's 发布"Why is dynamic SQL bad?",因为从性能的角度来看,您应该尽可能避免使用动态SQL。另请注意,您对SQL injection 更加开放,应该使用绑定变量和DBMS_ASSERT 来帮助防范它。

【讨论】:

感谢您的解决方案!我想检查是否可以创建、插入和选择值... @Aspirant,我的建议是创建表格,插入表格并选择值...【参考方案2】:

如果您多次运行该程序,即使在修改程序以将 select 语句作为动态 SQL 运行或使用 return into 子句后,您也会收到错误。 因为当你第一次运行程序时,它会毫无问题地创建表,但是当你下次运行它时,因为表已经第一次创建并且你没有 drop 语句,它会导致错误:“表已经存在于数据库”。 所以我的建议是在 pl/sql 程序中创建表之前,请始终检查数据库中是否已经存在同名的表。您可以使用存储元数据的数据字典视图/系统表来执行此检查,具体取决于您的数据库类型。

例如在 Oracle 中,您可以使用以下视图来决定是否需要创建表:

DBA_TABLES , ALL_TABLES, USER_TABLES

【讨论】:

以上是关于PL/SQL 中的 DDL 语句?的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQLPL/SQL中动态执行SQL语句

PL/SQL开发中动态SQL的使用方法

什么是PL/SQL

Oracle_PL/SQL 动态sql

常用的PL/SQL开发原则

带有动态 sql 的 PL/SQL 触发器