1

私はOracleが初めてで、これに苦労しています:

DECLARE 
 cnt NUMBER;

BEGIN
 SELECT COUNT(*) INTO cnt FROM all_tables WHERE table_name like 'Newtable'; 
 IF(cnt=0) THEN
   EXECUTE IMMEDIATE 'CREATE TABLE Newtable ....etc';
 END IF;
 COMMIT;

 SELECT COUNT(*) INTO cnt FROM Newtable where id='something'
 IF (cnt=0) THEN
   EXECUTE IMMEDIATE 'INSERT INTO Newtable ....etc';
 END IF;
END;

これはクラッシュし続け、挿入行に「PL/SQL: ORA-00942: テーブルまたはビューが存在しません」というメッセージが表示されます。どうすればこれを回避できますか? または、私は何を間違っていますか?これら 2 つのステートメント (実際にはもっと多くのことです) を 1 つのトランザクションで実行したいと考えています。

4

3 に答える 3

0

Oracle は、次の 2 つのステップでブロックの実行を処理します。

  1. 最初にブロックを解析し、内部表現 (いわゆる「P コード」) にコンパイルします。
  2. 次に、P コードを実行します (アーキテクチャと Oracle のバージョンに応じて、マシン コードに解釈またはコンパイルされる場合があります)。

コードをコンパイルするために、Oracle は参照されるテーブルの名前 (およびスキーマ!) を認識している必要があります。テーブルがまだ存在しないため、スキーマがなく、コードがコンパイルされません。

1 つの大きなトランザクションでテーブルを作成するという意図に対して: これは機能しません。Oracle は常に、DDL ステートメント( 、、(!) など)の前後で現在のトランザクションを暗黙的にコミットします。そのため、各 の後、Oracle は現在のトランザクションをコミットし、新しいトランザクションを開始します。create tablealter tabletruncate tablecreate table

于 2013-08-14T14:22:14.920 に答える
0

次のアプローチを試してください。つまり、作成と挿入は 2 つの異なるブロックにあります。

DECLARE
    cnt NUMBER;
BEGIN
    SELECT  COUNT (*)
      INTO  cnt
      FROM  all_tables
     WHERE  table_name LIKE 'Newtable';

    IF (cnt = 0)
    THEN
        EXECUTE IMMEDIATE 'CREATE TABLE Newtable(c1 varchar2(256))';
    END IF;
END;

DECLARE
    cnt2    NUMBER;
BEGIN
    SELECT  COUNT (*)
      INTO  cnt2
      FROM  newtable
     WHERE  c1 = 'jack';

    IF (cnt2 = 0)
    THEN
        EXECUTE IMMEDIATE 'INSERT INTO Newtable values(''jill'')';
    END IF;
END;
于 2013-08-14T10:24:18.347 に答える