6

我正在尝试下面的代码在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 块中?

4

2 回答 2

13

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

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。尽管您可以使用语法,但在这种特殊情况下实际上不需要执行 SELECT 。returning into

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 的帖子“为什么动态 SQL 不好?” 从性能的角度来看,您应该尽可能避免使用动态 SQL。另请注意,您对SQL 注入更加开放,应该使用绑定变量并DBMS_ASSERT帮助防范它。

于 2012-06-30T10:16:24.470 回答
2

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

对于 Oracle 中的示例,您可以使用以下视图来决定是否需要创建表:

DBA_TABLES、ALL_TABLES、USER_TABLES

于 2013-02-11T21:28:21.347 回答