2010-11-20 16 views
4

Je dispose d'un fichier .sql qui a une séquence de créer des déclarations de table, comme ceci:Comment puis-je exécuter uniquement des instructions sélectives à partir d'un fichier SQL?

crtab.sql

define ll='&1'; 
define ul='&2'; 

create table TAB1 (...); 
create table TAB2 (...); 
create table TAB3 (...); 
... 
create table TAB1000 (...); 

L'utilisateur passe comme arguments deux paramètres - la limite inférieure ll et la limite supérieure ul, ce qui signifie la plage de numéros de table à créer.


Par exemple,

sqlplus crtab.sql 3 67 

ne créer que des tables TAB3-TAB67.

Comment puis-je implémenter cette logique dans mon fichier .sql?

+0

Est-ce que ce doit être un fichier .sql? Ou pouvez-vous utiliser un script shell - parce que cela semble être l'approche la plus simple pour moi. – Benubird

Répondre

1

En supposant que les structures de table sont les mêmes, vous feriez mieux de créer & en exécutant des instructions sql dynamiques dans une boucle, en fonction de vos ll et ul. par exemple. (en syntaxe de serveur SQL)

declare @sql varchar(1000) 
declare @i int set @i = @ll 
while @i <= @ul begin 
    set @sql = 'create table TAB' + cast(@i as varchar) + '(...);' 
    exec @sql 
    set @i = @i + 1 
end 

Si les structures de la table sont différentes, placez simplement une instruction if autour de chaque création.

+0

les structures de la table sont différentes. C'est pourquoi je ne les ai pas dans une boucle en premier lieu. – Lazer

2
  1. Utilisez associative array, et insérez toutes les requêtes dans ce tableau de la manière suivante:

myArray(1) := 'CREATE TAB 1 ...';

...

myArray(1000) := 'CREATE TAB 1000 ...';

2. boucle par ll à ul un e exécuter ces requêtes, à savoir

for i in ll..ul 
    loop 
     @sql = myArray(i); 
     exec @sql; 
    end loop; 

Je suis désolé pour les erreurs de syntaxe.

+0

-1 pas très utile, c'est Oracle –

2

Peut-être comme ces

CREATE OR REPLACE PROCEDURE TABS_V1 (ll number, ul number) IS 
BEGIN 
    IF 1 BETWEEN ll AND ul THEN 
      EXECUTE IMMEDIATE 'create table TAB1 (...)'; 
    END IF; 
    IF 2 BETWEEN ll AND ul THEN 
      EXECUTE IMMEDIATE 'create table TAB2 (...)'; 
    END IF; 
    IF 3 BETWEEN ll AND ul THEN 
      EXECUTE IMMEDIATE 'create table TAB3 (...)'; 
    END IF; 

    ... 

    IF 1000 BETWEEN ll AND ul THEN 
      EXECUTE IMMEDIATE 'create table TAB1000 (...)'; 
    END IF; 
END; 



CREATE OR REPLACE PROCEDURE TABS_V2 (ll number, ul number) IS 
    TYPE tabs IS TABLE OF VARCHAR2(4000) INDEX BY NUMBER; 
    tabs all_tabs; 
BEGIN 
    all_tabs(1) = 'create table TAB1 (...)'; 
    all_tabs(1) = 'create table TAB2 (...)'; 
    all_tabs(1) = 'create table TAB3 (...)'; 
    ... 
    all_tabs(1000) = 'create table TAB1000 (...)'; 

    FOR cnt IN ll .. ul LOOP 
     EXECUTE IMMEDIATE all_tabs(cnt); 
    END LOOP; 
END; 
+0

Je pense que vous vouliez nommer après votre BEGIN all_tabs (1) ... all_tabs (2) ... all_tabs (3) etc. –

1

Il y a plusieurs façons de le faire. D'abord, vous pouvez utiliser un bloc anonyme avec une table imbriquée des instructions ou un tableau associatif des instructions. L'approche de la table imbriquée nécessite un peu moins de changements dans votre script existant, mais il y a un risque que les numéros ne soient pas en séquence. Notez que j'utilise le mécanisme de citations alternatif, par ex. q '[character] ... [character]', juste au cas où votre DDL contient des apostrophes.

Ce code est similaire à certaines des autres réponses, mais avec la syntaxe Oracle et ne nécessite pas la création d'objets supplémentaires.

script table imbriquée:

--Only create the tables between the two values (nested table) 
declare 
    type varchar_tab is table of varchar2(32767); 
    table_statements varchar_tab := varchar_tab(
    q'!create table tab1 (test1 number)!', 
    q'!create table tab2 (test1 number)!', 
    q'!create table tab3 (test1 number)!', 
    q'!create table tab4 (test1 number)!' 
); 
begin 
    for i in &1 .. &2 loop 
    execute immediate table_statements(i); 
    end loop; 
end; 
/

script tableau Associatif:

--Only create the tables between the two values (associative array) 
declare 
    type varchar_tab is table of varchar2(32767) index by number; 
    table_statements varchar_tab; 
begin 
    table_statements(1) := q'!create table tab1 (test1 number)!'; 
    table_statements(2) := q'!create table tab2 (test1 number)!'; 
    table_statements(3) := q'!create table tab3 (test1 number)!'; 
    table_statements(4) := q'!create table tab4 (test1 number)!'; 

    --Only create the tables between the two values 
    for i in &1 .. &2 loop 
    execute immediate table_statements(i); 
    end loop; 
end; 
/

Si vous êtes à la recherche d'une façon de garder votre script presque identique à sa forme actuelle, une autre approche serait de exécuter le script entier et avoir un bloc anonyme à la fin qui supprime les tables indésirables. Cela maintient le début de votre script très simple, mais il peut évidemment y avoir quelques soucis avec la suppression automatique des tables.

--Drop all the tables except for those within the range 
declare 
    table_does_not_exist exception; 
    pragma exception_init(table_does_not_exist, -00942); 
begin 
    for i in 1 .. 1000 loop 
    if i between &1 and &2 then 
     null; 
    else 
     begin 
     execute immediate 'drop table tab'||i; 
     exception when table_does_not_exist then null; 
     end; 
    end if; 
    end loop; 
end; 
/
0

Une façon de le faire piraté serait d'utiliser le préprocesseur C et #if directives pour inclure ou non chaque énoncé baed sur certaines macros que vous définissez sur la ligne de commande. Ensuite, exécutez le fichier prétraité plutôt que l'original.