web-dev-qa-db-fra.com

Comment puis-je vérifier que si un synonyme existe déjà, ne créez pas de synonyme?

J'utilise Oracle SQL Developer 2.1 pour créer un synonyme.

CREATE OR REPLACE SYNONYM "ETKS_PR_RW"."SQ_CLDOS_ATCHMNT_ID" 
    FOR "CLDOS_ONLINE_DBA"."SQ_CLDOS_ATCHMNT_ID";

Comment puis-je vérifier que si ce synonyme existe déjà, ne le créez pas s'il le fait.

10
SOF User

Comme vous utilisez le mot clé replace, il n'est pas nécessaire de vérifier si le synonyme existe en premier. Vous écraserez tout synonyme existant avec le nom précédent. 

La seule raison pour laquelle vous évitez d'utiliser replace est si vous pouvez avoir un synonyme différent portant le même nom. Si votre base de données est bien organisée, cela ne devrait pas arriver. Vous devez toujours savoir ce que sont tous vos objets et où se trouvent les synonymes.

Toutefois, si vous le souhaitez, plusieurs options sont possibles:

  1. Supprimer replace. L'instruction émettra une erreur si le synonyme existe déjà et ne sera pas écrasé.
  2. Interrogez le dictionnaire de données, car vous êtes dans plusieurs schémas all_synonyms semble être le meilleur choix.

    select *
      from all_synonyms
     where owner = 'ETKS_PR_RW'
       and synonym_name = 'SQ_CLDOS_ATCHMNT_ID';
    

Si vous voulez les combiner en un seul bloc, vous pouvez faire quelque chose comme ceci:

declare

   l_exists number;

begin
   -- check whether the synonym exists
   select 1
     into l_exists
     from all_synonyms
    where owner = 'ETKS_PR_RW'
      and synonym_name = 'SQ_CLDOS_ATCHMNT_ID';

-- an error gets raise if it doesn-t.
exception when no_data_found then
   -- DDL has to be done inside execute immediate in a block.
   execute immediate 'CREATE OR REPLACE SYNONYM ETKS_PR_RW.SQ_CLDOS_ATCHMNT_ID 
                   FOR CLDOS_ONLINE_DBA.SQ_CLDOS_ATCHMNT_ID';

end;
/

Ne séparez pas s'il vous plaît, ne séparez pas vos noms d'objet. Oracle peut avoir des objets en boîtier, mais cela en vaut très rarement la peine. Tous les objets seront automatiquement mis en majuscule afin que vous n'ayez pas besoin du ".

24
Ben

Je pense que si vous supprimez le mot clé OR REPLACE, il vous proposera de le signaler.

Ou vous pouvez créer du code pl/sql en utilisant ces tables 

desc dba_synonyms
desc user_synonyms

Pour le rendre plus flexible et personnalisé

En supposant que Oracle PL/SQL

DECLARE
    src_schema    VARCHAR2(256) := 'EMPIK_DYNAMO_01';
    target_schema VARCHAR2(256) := 'EMPIK_PORTAL_BETA_1';
    CURSOR src_objects IS
      SELECT table_name AS object_name
      FROM   all_all_tables
      WHERE  owner = src_schema
      UNION
      SELECT sequence_name AS object_name
      FROM   all_sequences
      WHERE  sequence_owner = src_schema;
BEGIN
    FOR next_row IN src_objects LOOP
        BEGIN
            EXECUTE IMMEDIATE 'CREATE or REPLACE SYNONYM '|| target_schema|| '.'
            ||
            next_row.object_name|| ' for '|| src_schema|| '.'||
            next_row.object_name;
        EXCEPTION
            WHEN OTHERS THEN
              dbms_output.Put_line('ERROR WHILE CREATING SYNONYM FOR: '
                                   || next_row.object_name);

              dbms_output.Put_line(SQLERRM);
        END;
    END LOOP;
END;

/ 

Voici la personnalisation de votre problème

BEGIN
    EXECUTE IMMEDIATE 'CREATE or REPLACE SYNONYM ETKS_PR_RW.SQ_CLDOS_ATCHMNT_ID FOR CLDOS_ONLINE_DBA.SQ_CLDOS_ATCHMNT_ID';  
EXCEPTION
    WHEN OTHERS THEN
      dbms_output.Put_line ('ERROR WHILE CREATING SYNONYM FOR: SQ_CLDOS_ATCHMNT_ID');
      dbms_output.Put_line (SQLERRM);
END; 
0
shareef