# SQL Skript "ignore this error"



## dior (10. Feb 2012)

Hallo,

ich schreibe ein paar ASCII Files in eine Oracle DB. Problem ist, die Spaltennamen unterscheiden sich bei den jeweiligen Files etwas.
D.H. es kann sein das ich mit "Alter Table" ein paar spalten hinzufügen muss (die Namen der Spalten entnehme ich der ASCII Datei)

Problem ist jetzt, ich lese mir die Namen der Spalten mit einem StringBuffer aus und mach mir einen Gesamtstring der in etwa so aussieht:


```
Alter Table TESTTABLE2 ADD ("A1" VARCHAR2(20 BYTE)); Alter Table TESTTABLE2 ADD ("A2" VARCHAR2(20 BYTE)); ........
```

Problem: Die SQL Anweisung bricht evtl. schon beim ersten Alter Table ab da der Wert A1 schon vorhanden ist. 
Wie kann ich (wie z.B. in Toad) "ignore this Error" "sagen" damit er jedes Alter Table ausführt, da hier z.B. das A2 nicht vorhanden ist und hinzugefügt werden muss?


----------



## Gast2 (10. Feb 2012)

Entweder du setzt anonyme PL/SQL Blocks ab die den Fehler im ALTER statement ignorieren oder aber du machst jedes Statement in einem eigenen DDL Query.


```
String[] sqls = "Alter Table TESTTABLE2 ADD ("A1" VARCHAR2(20 BYTE)); Alter Table TESTTABLE2 ADD ("A2" VARCHAR2(20 BYTE)); ........".split(";");

for(String sql : sqls){
  Statement stmt = con.createStatment();
  stmt.execute(sql+";");
}
```


----------



## HoaX (10. Feb 2012)

Oder du gehst über die Metadaten und schaust vorher nach ob es die Spalte schon gibt.


----------



## nocturne (11. Feb 2012)

Oracle hm?

WHENEVER SQLERROR

WHENEVER SQLERROR

Gruß


----------



## XHelp (11. Feb 2012)

Oder try-catch in die Schleife ziehen.
P.S. passt nicht ganz, hab es anfangs falsch gelesen


----------



## dior (13. Feb 2012)

Hi,

Danke für die Antworte. Ich habe probiert das umzusetzten aber es gelingt mir nicht!

Das ist mein String den ich erzeuge: (text = hier lese ich die entsprechenden Werte aus einer txt datei aus)

```
AlterTableString = header2AlterTable.append("Alter Table DMT.").append(tableName).append(" ADD (\"").append(text.substring(anfang2+1, ende2)).append("\" " + "VARCHAR2(20 BYTE)" + "); ").toString();
.
.
.
```

der Aufruf erfolg mit:

```
stmt.executeQuery(AlterTableString);
```

Wenn ich AlterTableString mit println ausgeben und in Toad probiere (test mit WHENEVER SQLERROR CONTINUE funktioniert es als "run as Skript" aber nicht mit "excecute statement"

Wie könnte ich das umschreiben das es läuft?


----------



## Gast2 (13. Feb 2012)

Probier es mal so:


```
StringBuilder alterTableString = new StringBuilder();
        	alterTableString.append("BEGIN ");
        	
        	// für alle deine satetments
        	alterTableString.append("BEGIN ");
        	alterTableString.append("Alter Table DMT.");
        	alterTableString.append(tableName);
        	alterTableString.append(" ADD(\"");
        	alterTableString.append(text.substring(anfang2+1, ende2));
        	alterTableString.append("\"VARCHAR2(20 BYTE)); EXCEPTION WHEN others THEN NULL; END;");
        	
        	
        	// am ende 
        	alterTableString.append("END; ");
        	CallableStatement cstmt = conn.prepareCall( alterTableString.toString() );
        	cstmt.execute();
```


----------



## dior (14. Feb 2012)

Vielen Vielen Dank!!!!

musste nur noch execute immediate ' vor alter Table schreiben! 


hier nochmal für alle die das Thema auch interessiert mein funktionierender Code:


```
public class DbAlterTable_test {
    
    
    public static String header2ohne;
    public static String header2String;
    public static String header2AlterTable;
    public static String AlterTableString;
        
    public static void main(String[] args) throws Exception{
       Connection conn = db_input.DbInsert.getConnection(); 
       
       File file = Variablen.Variablen.file;
        String tableName = Variablen.Variablen.tableName;
        StringBuilder contents = new StringBuilder();
        BufferedReader reader = null;
        
        StringBuilder header2 = new StringBuilder();
        StringBuilder alterTableString = new StringBuilder();

        alterTableString.append("BEGIN ");
        
       try {
            reader = new BufferedReader(new FileReader(file));
            String text = null;

            // repeat until all lines is read
            while ((text = reader.readLine()) != null) {
                contents.append(text)
                    .append(System.getProperty(
                        "line.separator"));
                
              
            int anfang2 = text.indexOf(" ");
            int ende2 = text.indexOf("  "); 
               
            
            // für alle deine statetments
            alterTableString.append("BEGIN ");
            alterTableString.append("execute immediate 'Alter Table DMT.");
            alterTableString.append(tableName);
            alterTableString.append(" ADD(\"");
            alterTableString.append(text.substring(anfang2+1, ende2));
            alterTableString.append("\"VARCHAR2(20 BYTE))'; EXCEPTION WHEN others THEN NULL; END;");
            
                            
            }
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            try {
             // zum Test des Statements   
            System.out.println(alterTableString);
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
            }
        }
       
            // am ende 
            alterTableString.append("END; ");
            CallableStatement cstmt = conn.prepareCall( alterTableString.toString() );
            cstmt.execute();
   
       
    }
    
    
    
    
}
```







*D A N K E*


----------



## Gast2 (14. Feb 2012)

dior hat gesagt.:


> Vielen Vielen Dank!!!!
> 
> musste nur noch execute immediate ' vor alter Table schreiben!



Right... Das hatte ich vergessen, aber da bist du ja selber drauf gekommen. 

Das Beste wäre wenn du noch mit DMBS_SQL deine DDL/DML Statements parsen lässt. So wie es im Moment ist kannst du ein Problem mit SQL Injections haben.

DBMS_SQL


----------

