Errore ORA-01000 massimo numero cursori aperto

mirkomirko

Nuovo Utente
30 Lug 2012
25
4
3
Salve a tutti,ho un programma Java che carica nel database di oracle,uno script di insert di 1.3GB,inserimenti gestiti tramite l'aggiunta batch,che prende 1000 istruzioni alla volta,le connessioni che creo con il database però,mi sembra di chiuderle tutte e non capisco come mai mi dia questo errore.
Come posso modificare il numero massimo di cursori che si possono aprire?
Il pezzo di codice che si occupa degli inserimenti è il seguente
Codice:
public static void reader(){
        FileReader  temp;
        BufferedReader brtemp;
        String s;
        StringBuffer sb = new StringBuffer();
		try
		{
			temp = new FileReader("C:/Users/Mirko/Desktop/Script/temp.sql");
			brtemp = new BufferedReader(temp);
			while((s = brtemp.readLine()) != null)  
            			{  
            				sb.append(s);  
            			}  
            			//br.close();  
  
            			// here is our splitter ! We use ";" as a delimiter for each request  
            			// then we are sure to have well formed statements  
            			String[] inst = sb.toString().split(";"); 
            			conn.setAutoCommit(false);
            			Statement st = conn.createStatement();  
            	
            		
  
            			for(int i = 0; i<inst.length; i++)  
            			{  
            				// we ensure that there is no spaces before or after the request string  
            				// in order to not execute empty statements  
            				if(!inst[i].trim().equals(""))  
            				{  
            					st.addBatch(inst[i]);
            					//st.executeUpdate(inst[i]);  
            					System.out.println(">>"+inst[i]);  
            				}  
            			}
            			st.executeBatch();
            			conn.commit();
            			st.close();

            			brtemp.close();
          
            }
		catch(Exception e)  
    	{  
    		System.out.println("*** Error : "+e.toString());  
    		System.out.println("*** ");  
    		System.out.println("*** Error : ");  
    		e.printStackTrace();  
    		System.out.println("################################################");  
    		System.out.println(sb.toString());  
    	}
          
	}
Apparentemente mi sembra di chiudere tutto,grazie mille per le eventuali risposte!
 

marino51

Utente Attivo
28 Feb 2013
2.927
166
63
Lombardia
inserimenti gestiti tramite l'aggiunta batch,che prende 1000 istruzioni alla volta
nel tuo script non vedo la gestione dei 1000 ...., forse non capisco io o hai postato uno script diverso da quello che stai usando
ciao
Marino
 

mirkomirko

Nuovo Utente
30 Lug 2012
25
4
3
Questo metodo prende gia un file temp di 1000 righe comunque posto la parte in cui dal file iniziale creo i blocchi di 1000 righe
Codice:
public class JDBCconnection{
        public static String URL = "jdbc:oracle:thin:@MIRKO-PC:1521:prova";
	public static String USER = "sys as SYSDBA";
	public static String PASSWORD = "Provaprova2";
	public static Connection conn;
	public static void main(String[] args) throws ClassNotFoundException, SQLException{
		Class.forName("oracle.jdbc.driver.OracleDriver");
		conn = DriverManager.getConnection(URL,USER,PASSWORD);
		
		StringBuffer sb = new StringBuffer();  
		int righe = 0;
		long start = System.currentTimeMillis();
		try  
		{  
        	 FileReader frPopRA = new FileReader(new File("C:/Users/Mirko/Desktop/Script/popolamento-r-a.sql"));

        	FileWriter wr;
        	
        	BufferedReader br = new BufferedReader(frPopRA);
        	BufferedWriter bw;
        	//BufferedReader brtemp;
        	String line;
            
        	wr = new FileWriter("C:/Users/Mirko/Desktop/Script/temp.sql");
        	bw = new BufferedWriter(wr);
        	
            while(true){
            	line = br.readLine();
            	if(line == null){
            		bw.flush();
            		reader();
            		break;
            	}
            	else{
            		righe++;
            		bw.write(line+"\n");
            	}
            		if(righe == 1000){
            			righe = 0;
            			bw.flush();
            			reader();
            			//temp = new FileReader("C:/Users/Mirko/Desktop/Script/temp.sql");
                    	wr = new FileWriter("C:/Users/Mirko/Desktop/Script/temp.sql");
                    	bw = new BufferedWriter(wr);
            			//brtemp = new BufferedReader(temp);
            		}
            }
            bw.close();
            br.close();
            conn.close();
        }
    	catch(Exception e)  
    	{  
    		System.out.println("*** Error : "+e.toString());  
    		System.out.println("*** ");  
    		System.out.println("*** Error : ");  
    		e.printStackTrace();  
    		System.out.println("################################################");  
    		System.out.println(sb.toString());  
    	}
    	long end = System.currentTimeMillis();
    	System.out.print("Tempo di esecuzione "+((end-start)/1000)/60+" minuti");  
    	
    }
ecco qui ^_^ .
 

marino51

Utente Attivo
28 Feb 2013
2.927
166
63
Lombardia
per favore usa un file da 200 record,
fai la prima prova lasciando 1000, gestisce i 200 record in una tornata, deve darti errore,
poi fai la stessa prova ma mettendo 49 invece di 1000, gestisce 49 record per volta, che succede ?
ciao
 
Ultima modifica:

mirkomirko

Nuovo Utente
30 Lug 2012
25
4
3
per favore usa un file da 200 record,
fai la prima prova lasciando 1000, gestisce i 200 record in una tornata, deve darti errore,
poi fai la stessa prova ma mettendo 49 invece di 1000, gestisce 49 record per volta, che succede ?
ciao
La prova con 200 record prendendone 1000 alla volta riesce perfettamente,e anche prendendone 49.
Il problema penso sia nei cursori che rimangono aperti,ma a quanto vedo chiudo tutte le connessioni che apro,non dovrebbe darmi quel problema. Grazie mille!
 

marino51

Utente Attivo
28 Feb 2013
2.927
166
63
Lombardia
La prova con 200 record prendendone 1000 alla volta riesce perfettamente,e anche prendendone 49.
Il problema penso sia nei cursori che rimangono aperti,ma a quanto vedo chiudo tutte le connessioni che apro,non dovrebbe darmi quel problema. Grazie mille!
ti cito quanto dice il manuale "oracle 8" a proposito delle operazioni fatte con odbc (jdbc),

Ogni istruzione SQL eseguita da un'origine dati ODBC dispone di un handle di istruzione associata (hstmt)
utilizzato per identificare l'istruzione. In Oracle, ogni hstmt utilizza un cursore.
I cursori sono una risorsa limitata in Oracle e se non vengono eliminati i cursori, il database può dare problemi.

quindi non sei tu che lasci cursori aperti ma il modo come gestisci l'insert dei record,

in prima battuta puoi provare a ridurre a 500 il numero dei record

in seconda, puoi lasciare l'autocommit attivato e togliere il commit alla chiusura del blocco
se questa impostazione non ti serve per rendere più agevole un eventuale ripristino in caso di errore nell'input

un altro modo può essere quello di inserire dei commit parziali nel primo script che hai postato, quello che scrive sul db, devi cambiare appena appena il codice

puoi anche impegnarti a modificare il parametro che regola il numero dei cursori per il tuo script,
ma potresti poi incontrare altri problemi, in ogni caso ti segnalo due link che possono darti la via ..
http://orafaq.com/node/758
http://docs.oracle.com/cd/B19306_01/server.102/b14237/initparams138.htm
ciao
Marino