36

Oracleで作成する前にテーブルが存在するかどうかを確認しようとしています。Stackoverflowなどからの投稿のほとんども検索してください。いくつかのクエリを見つけましたが、それは私にとってはうまくいきませんでした。

IF((SELECT count(*) FROM dba_tables where table_name = 'EMPLOYEE') <= 0)
THEN
create table EMPLOYEE
(
ID NUMBER(3),
NAME VARCHAR2(30) NOT NULL
)
END IF;

エラーが発生します

Error: ORA-00900: invalid SQL statement
SQLState:  42000
ErrorCode: 900
Position: 1

条件の構文を検索しますがIF、これも書き込みだと思います。私に提案してください...

4

9 に答える 9

42

Reneもコメントしているように、最初にチェックしてからテーブルを作成することは非常にまれです。メソッドに従って実行中のコードが必要な場合、これは次のようになります。

declare
nCount NUMBER;
v_sql LONG;

begin
SELECT count(*) into nCount FROM dba_tables where table_name = 'EMPLOYEE';
IF(nCount <= 0)
THEN
v_sql:='
create table EMPLOYEE
(
ID NUMBER(3),
NAME VARCHAR2(30) NOT NULL
)';
execute immediate v_sql;

END IF;
end;

しかし、私はむしろ例外に追いつきたいので、不要なコード行を節約できます。

declare
v_sql LONG;
begin

v_sql:='create table EMPLOYEE
  (
  ID NUMBER(3),
  NAME VARCHAR2(30) NOT NULL
  )';
execute immediate v_sql;

EXCEPTION
    WHEN OTHERS THEN
      IF SQLCODE = -955 THEN
        NULL; -- suppresses ORA-00955 exception
      ELSE
         RAISE;
      END IF;
END; 
/
于 2013-03-26T09:16:14.850 に答える
7

このトピックは少し古いことは知っていますが、誰かに役立つかもしれないことをしたと思うので、投稿します。

このスレッドの回答からの提案を手順にまとめました。

CREATE OR REPLACE PROCEDURE create_table_if_doesnt_exist(
  p_table_name VARCHAR2,
  create_table_query VARCHAR2
) AUTHID CURRENT_USER IS
  n NUMBER;
BEGIN
  SELECT COUNT(*) INTO n FROM user_tables WHERE table_name = UPPER(p_table_name);
  IF (n = 0) THEN
    EXECUTE IMMEDIATE create_table_query;
  END IF;
END;

その後、次の方法で使用できます。

call create_table_if_doesnt_exist('my_table', 'CREATE TABLE my_table (
        id NUMBER(19) NOT NULL PRIMARY KEY,
        text VARCHAR2(4000),
        modified_time TIMESTAMP
  )'
);

テーブル名を2回渡すのはちょっと冗長だと思いますが、ここではそれが最も簡単だと思います。

誰かが上記が役に立つと思うことを願っています:-)。

于 2016-11-03T15:52:18.907 に答える
2

してみてください:

SET SERVEROUTPUT ON
DECLARE
v_emp int:=0;
BEGIN
  SELECT count(*) into v_emp FROM dba_tables where table_name = 'EMPLOYEE'; 

  if v_emp<=0 then
     EXECUTE IMMEDIATE 'create table EMPLOYEE ( ID NUMBER(3), NAME VARCHAR2(30) NOT NULL)';
  end if;
END;
于 2013-03-26T06:56:52.207 に答える
2
declare n number(10);

begin
   select count(*) into n from tab where tname='TEST';

   if (n = 0) then 
      execute immediate 
      'create table TEST ( ID NUMBER(3), NAME VARCHAR2 (30) NOT NULL)';
   end if;
end;
于 2016-01-23T20:43:25.293 に答える
2

私の解決策は、スレッドで最高のアイデアをまとめただけで、少し改善されています。再利用を容易にするために専用のプロシージャ(@Tomasz Borowiec)を使用し、コードを減らしてプロシージャ内の冗長なテーブル名を取り除くために例外処理(@Tobias Twardon)を使用します。

DECLARE

    PROCEDURE create_table_if_doesnt_exist(
        p_create_table_query VARCHAR2
    ) IS
    BEGIN
        EXECUTE IMMEDIATE p_create_table_query;
    EXCEPTION
        WHEN OTHERS THEN
        -- suppresses "name is already being used" exception
        IF SQLCODE = -955 THEN
            NULL; 
        END IF;
    END;

BEGIN
    create_table_if_doesnt_exist('
        CREATE TABLE "MY_TABLE" (
            "ID" NUMBER(19) NOT NULL PRIMARY KEY,
            "TEXT" VARCHAR2(4000),
            "MOD_TIME" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ');
END;
/
于 2018-06-13T14:14:27.757 に答える
1

作成前のテストに依存するソリューションは、別のプロセスが存在しないことをテストしてから作成するまでの間にテーブルを作成する「競合」状態に陥る可能性があります。-私が知っているマイナーなポイント。

于 2018-09-28T05:15:03.447 に答える
1

--特定のスキーマのテーブルをチェックします。

declare n number(10);

begin
    Select count(*) into n  from SYS.All_All_Tables where owner = 'MYSCHEMA' and TABLE_NAME =  'EMPLOYEE';

   if (n = 0) then 
     execute immediate 
     'create table MYSCHEMA.EMPLOYEE ( ID NUMBER(3), NAME VARCHAR2(30) NOT NULL)';      
   end if;
end;
于 2019-05-17T14:09:11.387 に答える
1

すでに提供されている答えはたくさんあり、多くも理にかなっています。

ただの警告であると言う人もいれば、警告を無効にする一時的な方法を与える人もいます。これらはすべて機能しますが、DB内のトランザクション数が多い場合はリスクが高まります

私は今日同様の状況に遭遇しました、そしてここに私が思いついた非常に単純なクエリがあります...

declare
begin
  execute immediate '
    create table "TBL" ("ID" number not null)';
  exception when others then
    if SQLCODE = -955 then null; else raise; end if;
end;
/

955は失敗コードです。

これは簡単です。クエリの実行中に例外が発生した場合、例外は抑制されます。とに同じものを使用できSQLますOracle

于 2020-04-23T11:19:53.957 に答える
0

宣言する必要はなく、カウントも適用されます。

begin
for rec in (select 1 from user_tables where table_name = 'YOUR_TABLE')
-- or
-- for rec in (select 1 from all_tables where table_name = 'YOUR_TABLE' and owner = 'YOU')
loop
    execute immediate 'create table your_table as (f1 char(1))';
end loop;
end;
/

良いモードになりますチェック機能を作成します

create or replace function this_object_exists (p_obj_name user_objects.object_name%type) return boolean
is
begin
   for rec in (select 1 from user_objects where object_name = upper(p_obj_name))
   loop
        return true;
   end loop;
   return false;
end this_object_exists;

したがって、チェックに使用するコードが存在します

インデックスパーティション テーブルサブパーティション 順序 テーブルパーティション
手順 LOBパーティション LOB インデックスサブパーティション
パッケージ パッケージボディ タイプボディ 引き金
索引 テーブル 見る 働き
シノニム タイプ 仕事 ..。
begin
if not this_object_exists('your_table') then
    execute immediate 'create table your_table as (f1 char(1))';
end if;
end;

また

begin
if this_object_exists('your_table') then
    execute immediate 'drop table your_table';
end if;
execute immediate 'create table your_table as (f1 char(1))';
end;
于 2021-05-16T09:24:32.583 に答える