在Oracle中执行即时语句时未创建临时表,导致ORA-00942错误。

3

根据这个答案,我正在尝试创建临时表,但是我遇到了异常ORA-00942:table or view does not exist。我认为'CREATE OR REPLACE GLOBAL TEMPORARY TABLE TempQandA(column1 number) ON COMMIT PRESERVE ROWS'语句有问题,在insert into TempQandA(column1) VALUES (1);处失败。
请查看下面的SQL语句。

DECLARE 
TransactioDetailId numeric := 3132;
HomePhoneNumber varchar(20);
MobileNumber varchar(20);
Email varchar(20);
whatever varchar(20);
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE GLOBAL TEMPORARY TABLE TempQandA(column1 number) ON COMMIT PRESERVE ROWS';

        BEGIN
        SELECT contactvalue into HomePhoneNumber  FROM customercontact CC
         inner join TRANSACTIONMAIN tm on tm.customerid = CC.customerid
         inner join transactiondetail td on td.transactionid = tm.transactionid
         where contacttypeid = 2 and td.transactiondetailid = TransactioDetailId;
         EXCEPTION
         WHEN NO_DATA_FOUND THEN
         HomePhoneNumber := NULL;
                         begin
                         SELECT  contactvalue into MobileNumber  FROM customercontact CC
                         inner join TRANSACTIONMAIN tm on tm.customerid = CC.customerid
                         inner join transactiondetail td on td.transactionid = tm.transactionid
                         where contacttypeid = 3 and td.transactiondetailid = TransactioDetailId;
                         EXCEPTION
                         WHEN NO_DATA_FOUND THEN
                         MobileNumber := NULL;
                                      begin
                                      SELECT  contactvalue into Email  FROM customercontact CC
                                      inner join TRANSACTIONMAIN tm on tm.customerid = CC.customerid
                                      inner join transactiondetail td on td.transactionid = tm.transactionid
                                      where contacttypeid = 1 and td.transactiondetailid = TransactioDetailId;
                                      EXCEPTION
                                      WHEN NO_DATA_FOUND THEN
                                      Email := NULL;

                                            begin
                                            insert into TempQandA(column1) VALUES (1);
                                             end;
                                     end;
                     end;
         end;
END;
2个回答

6

您可以动态创建 GTT,因此您的 INSERT 也应该是动态的。

请注意,PL/SQL 在执行之前会验证每个静态查询。这就是为什么即使在编译时也会出现 ORA-942 表或视图不存在 错误的原因!

因此,要避免这种语义检查,我们必须使调用动态化。

    BEGIN
    EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE TempQandA(column1 number) ON COMMIT PRESERVE ROWS';

.....

    EXECUTE IMMEDIATE ' insert into TempQandA(column1) VALUES (1)';
    END;

最后,您不应该在运行时创建GTT,以避免出现此类问题。 GTT无论如何都将本地到每个会话。

编辑:正如Lalit所说,GTTDDL不接受CREATE OR REPLACE


2
GTT创建语句不正确。OR REPLACE是无效选项。 - Lalit Kumar B

2

'CREATE GLOBAL TEMPORARY TABLE TempQandA(column1 NUMBER) ON COMMIT PRESERVE ROWS';

关键字REPLACE是不正确的。您需要简单地创建GTT并使用EXECUTE IMMEDIATE将值插入其中:

SQL> BEGIN
  2  EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE Temp_gtt(column1 number) ON COMMIT PRESERVE ROWS';
  3  EXECUTE IMMEDIATE 'insert into temp_gtt(column1) values(1)';
  4  END;
  5  /

PL/SQL procedure successfully completed.

SQL>
SQL> select * from temp_gtt;

   COLUMN1
----------
         1

SQL>

我们两个答案结合起来,回答了这个问题 ;) - Maheswaran Ravisankar
第一个问题出现在创建语句上 :-) 然后稍后是插入。 - Lalit Kumar B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接