web-dev-qa-db-fra.com

Vérifiez que la table existe ou non avant de la créer dans Oracle

Essayer de vérifier si la table existe avant de créer dans Oracle. Recherchez la plupart des publications de Stackoverflow et d'autres aussi. Trouvez une requête mais cela n'a pas fonctionné pour moi.

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;

Ce qui me donne une erreur

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

Je recherche la syntaxe pour la condition IF, je pense que ce qui est également écrit . S'il vous plaît me suggérer ....

24
Navnath

Comme René a également commenté, il est assez rare de vérifier d'abord et ensuite de créer la table . Si vous voulez avoir un code en cours d'exécution en fonction de votre méthode, ce sera:

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;

Mais je préférerais aller chercher l'exception, cela vous évite des lignes de code inutiles: 

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; 
/
22
Tobias Twardon

S'il vous plaît essayez:

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;
1
TechDo
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;
1
Amiya kumar nayak

Ma solution consiste simplement en une compilation des meilleures idées en fil, avec une petite amélioration . J'utilise à la fois une procédure dédiée (@Tomasz Borowiec) pour faciliter la réutilisation et une gestion des exceptions (@Tobias Twardon) pour réduire le code et éliminer les redondances. nom de la table dans la procédure.

DECLARE

    PROCEDURE create_table_if_doesnt_exist(
        p_create_table_query VARCHAR2
    ) IS
    BEGIN
        EXECUTE IMMEDIATE 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;
/
1

Je sais que ce sujet est un peu vieux, mais je pense avoir fait quelque chose qui pourrait être utile à quelqu'un, alors je le publie.

J'ai compilé les suggestions des réponses de ce fil dans une procédure:

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;

Vous pouvez ensuite l'utiliser de la manière suivante:

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
  )'
);

Je sais qu'il est un peu redondant de passer deux fois le nom de la table, mais je pense que c'est le plus facile ici.

J'espère que quelqu'un trouve ci-dessus utile :-).

1
Tomasz Borowiec

Toute solution reposant sur des tests avant la création peut s'exécuter dans une condition de «concurrence» lorsqu'un autre processus crée la table entre vous testant son inexistence et sa création. - Point mineur je sais.

0
mark d drake