Oracle : erreur ORA-00947 en insertion

Oracle : erreur ORA-00947 en insertion - C#/.NET managed - Programmation

Marsh Posté le 09-01-2006 à 20:08:02    

[:banguy]
vous le savez : Oracle me les casse, et royalement. sa dernière lubie : une erreur ORA-00947 qui me sort de je ne sais pas ou. pour info, cette erreur se déclenche quand le nombre de colonnes dans une requete INSERT est différent du nombre de valeurs qu'on insère. sauf que dans mon cas, c'est exactement le même... Oracle, O désespoir...
 
voici le code de mon appli C# qui s'occupe de l'insert, à partir de données contenues dans un fichier csv :
 

Code :
  1. [...]
  2. using (StreamReader sr = new StreamReader(file))
  3.                    {
  4.                        using (OracleConnection conn = new OracleConnection(strConnection))
  5.                        {
  6.                            try
  7.                            {
  8.                                conn.Open();
  9.                                command = conn.CreateCommand();
  10.                                String ligne = null;
  11.                                String[] champs = null;
  12.                                String delim = ";";
  13.                                char[] delimTab = delim.ToCharArray();
  14.                                pbImport.Visible = true;
  15.                                pbImport.Minimum = 0;
  16.                                pbImport.Maximum = CountLines(sr);
  17.                                pbImport.Value = 0;
  18.                                pbImport.Step = 1;
  19.                                file.Seek(0, SeekOrigin.Begin);
  20.  
  21.                                transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
  22.                                command.Transaction = transaction;
  23.  
  24.                                while ((ligne = sr.ReadLine()) != null)
  25.                                {
  26.                                    champs = ligne.Split(delimTab);
  27.                                    importOracle(champs);
  28.                                    pbImport.PerformStep();
  29.                                }
  30.                            }
  31.                            catch (InvalidOperationException ex)
  32.                            {
  33.                                MessageBox.Show("Connection non établie !" );
  34.                                transaction.Rollback();
  35.                                return;
  36.                            }
  37.                            catch (OracleException ex)
  38.                            {
  39.                                MessageBox.Show("Erreur Oracle : " + ex.Code.ToString());
  40.                                transaction.Rollback();
  41.                                return;
  42.                            }
  43.                            catch (Exception ex)
  44.                            {
  45.                                MessageBox.Show(ex.Message);
  46.                                transaction.Rollback();
  47.                                return;
  48.                            }
  49.                            transaction.Commit();
  50.                        }
  51.                    }
  52.                    MessageBox.Show("Importation terminée avec succés.", "Importation", MessageBoxButtons.OK, MessageBoxIcon.Information);
  53.                }
  54.            }
  55.        }
  56.  
  57.        private void importOracle(string[] lines)
  58.        {
  59.            try
  60.            {
  61.                string req = "INSERT INTO shema.table (col1, col2, col3, col4, col5, col6, col7, col8, col9) VALUES ("
  62.                            + "'STOCK','"
  63.                            + lines[0] + "','"
  64.                            + "CLI',"
  65.                            + "1,"
  66.                            + lines[1] + ","
  67.                            + lines[1] + ",'"
  68.                            + "E','"
  69.                            + txtDateDeb.Text + "','"
  70.                            + txtDateFin.Text + "')";
  71.                command.CommandText = req;
  72.                command.ExecuteNonQuery();
  73.            }
  74.            catch (InvalidOperationException ex)
  75.            {
  76.                throw;
  77.            }
  78.            catch (OracleException ex)
  79.            {
  80.                throw;
  81.            }
  82.        }


rien de bien méchant comme vous le voyez.... une caisse de Bordeaux à celui qui me dépatouille de ce merdier.
je soupçonne un bug de la classe OracleClient de .NET, mais bon, sait on jamais..
 
à vot bon coeur m'sieurs dames
 
edit: les noms des champs ne sont évidemment pas ceux que j'ai indiqués :D


Message édité par Harkonnen le 09-01-2006 à 20:12:05

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-01-2006 à 20:08:02   

Reply

Marsh Posté le 09-01-2006 à 20:16:51    

y'a pas de prepared statements en c#? [:totoz]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 09-01-2006 à 20:17:36    

(et figure toi que ça a un rapport avec la question, parce que normalement, il devrait refuser d'executer la requete si tous les params ne sont pas bindés, avant qu'oracle ait qqch à y dire)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 09-01-2006 à 21:30:25    

si si, y'a aussi les requetes paramétrées en C#, j'avais utilisé ça en tout premier lieu, mais ça faisait la même erreur [:skeye]
j'ai donc essayé avec le code que j'ai posté, sans plus de succés :sweat:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-01-2006 à 22:00:00    

Tu as vérifié que la requête est bien celle qui parvient au bouzin, aka Oracle, et que tous les paramètres sont bien là (log Oracle)
 
Quid si tu exécutes la requête depuis SQLPlus / Toad ?
 
Sans vouloir t'insulter et être TT pour 3 semaines : tu as bien affiché "req" et vérifié qu'elle est bien formée (on sait jamais, hein) ?
 
[:pingouino]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-01-2006 à 22:06:45    

oui, tout part chez Oracle, aucun souci là dessus, j'ai vérifié (c'est moi l'admin après tout bordel :o)
la requete marche sous Toad, et req contient la requete correcte ! j'ai vérifié tout ça, tu penses bien :o


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-01-2006 à 22:29:14    

bon, j'ai compris, faut que je me démerde :o
je vais recoder l'appli en Java histoire de vérifier si ça vient de .NET ou d'Oracle :o

Message cité 1 fois
Message édité par Harkonnen le 09-01-2006 à 22:29:38

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-01-2006 à 22:36:40    

a tout hasard, t'as testé le statut de "conn" pour voir son état ?


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 09-01-2006 à 22:44:15    

Harkonnen a écrit :

bon, j'ai compris, faut que je me démerde :o
je vais recoder l'appli en Java histoire de vérifier si ça vient de .NET ou d'Oracle :o


 
essaie de virer ton niveau d'isolation dans ta transaction (ne lui passe pas de parametre)
transaction = conn.BeginTransaction()

Reply

Marsh Posté le 09-01-2006 à 23:37:16    

Y aurait pas un caractère en trop dans lines[1] ?

Reply

Marsh Posté le 09-01-2006 à 23:37:16   

Reply

Marsh Posté le 09-01-2006 à 23:43:22    

une quote qui manque ou une virgule perdue ?
prepared stmt bordel :o


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 10-01-2006 à 09:42:27    

Dans lines[0] tu n'as pas de valeur avec une ' ? Dans ce cas il faut la doubler.
Et si col8 et col9 ont de types DATE, il faut mieux faire un "TO_DATE("+txtDateFin.Text1",'DDMMYYY')".
 
(J'aime bien le Pomerol d'une 10ène d'années par caisse de 12  :D )


Message édité par thecoin le 10-01-2006 à 09:42:53
Reply

Marsh Posté le 10-01-2006 à 11:33:49    

pardon, mais si il a vraiment essayé avec un prepared statement avant, ta caisse tu peux te la foutre au cucul [:itm]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 10-01-2006 à 11:50:07    

the real moins moins a écrit :

pardon, mais si il a vraiment essayé avec un prepared statement avant, ta caisse tu peux te la foutre au cucul [:itm]


 
Une requête SQL avec des paramètres de type DATE sans TO_DATE et des chaînes de caratères sans aucun traitement, tu peux la mettre au même endroit.  [:drizzt_do_urden]


Message édité par thecoin le 10-01-2006 à 11:50:31
Reply

Marsh Posté le 10-01-2006 à 11:57:46    

mais pas dans un prepared statement, broucouille [:mlc]
 
(ou alors l'implementation en c# est toute moisie ? )


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 10-01-2006 à 20:11:31    

bon, c'est réglé ! y'avait une tabulation dans le fichier csv qui foutait tout en l'air.
par contre : j'importe 12484 lignes, et c'est super lent. en effet, il faut une bonne heure pour tout importer.
quand je me suis aperçu de la présence du tab, et que le fait de l'enlever permettait au logiciel de refonctionner, j'ai remis ma requete paramétrée.
j'ai lu que ADODB (sur lequel repose la classe OracleConnection de .NET) était super lent et très peu optimisé. ceci explique peut etre celà.
néanmoins, que pensez vous de l'utilité du try/catch dans ma fonction importOracle() ? comme vous voyez, une fois l'exception catchée, je la rebalance directement à l'appelant, sans aucun traitement. ceci pour avoir une stacktrace la plus complète possible en cas de plantage.
par contre, est-ce vraiment utile finalement ? parce que de toute façon, si une exception doit péter, elle sera quand même catchée dans ma fonction principale. que pensez vous de virer le try/catch de la fonction importOracle() en terme de gain de vitesse ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-01-2006 à 20:28:46    

Harkonnen a écrit :


j'ai lu que ADODB (sur lequel repose la classe OracleConnection de .NET) était super lent et très peu optimisé. ceci explique peut etre celà.


 
MSDN:

Citation :


The .NET Framework Data Provider for Oracle provides access to an Oracle database using the Oracle Call Interface (OCI) as provided by Oracle Client software. The functionality of the data provider is designed to be similar to that of the .NET Framework data providers for SQL Server, OLE DB, and ODBC.


 
perdu [:pingouino]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-01-2006 à 21:10:50    

euh, ce serait pas un parfait exemple pour utiliser sql loader, plutôt?[:petrus dei]


Message édité par skeye le 10-01-2006 à 21:11:00

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 10-01-2006 à 21:17:04    

ben oui, mais que veux tu... ordre de mon chef : "ponds moi une appli facile à utiliser dans le langage que tu veux pour balancer un fichier csv de plusieurs milliers de lignes dans la base. pense surtout que ce sont des gens qui ne connaissent rien à l'info qui utiliseront ton programme"
 
donc bon, SQL Loader pour un end user, voilà quoi [:pingouino]
(ou alors je code un front end)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-01-2006 à 21:20:23    

Harkonnen a écrit :

ben oui, mais que veux tu... ordre de mon chef : "ponds moi une appli facile à utiliser dans le langage que tu veux pour balancer un fichier csv de plusieurs milliers de lignes dans la base. pense surtout que ce sont des gens qui ne connaissent rien à l'info qui utiliseront ton programme"
 
donc bon, SQL Loader pour un end user, voilà quoi [:pingouino]
(ou alors je code un front end)


 
Le front end me parait pas forcément une mauvaise idée...[:dawa]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 10-01-2006 à 22:48:47    

bon, jpense effectivement que je vais coder un front end pour sql loader, parce que plus ça va, plus c'est lent...
ce qui me tue, c'est que l'insertion des 2000 premieres lignes environ est hyper rapide, puis ensuite ça rame de plus en plus pour arriver péniblement à 12484 au bout d'une heure et demie [:pingouino]
 
questions à propos de sql loader :  
- ça gère les transactions ? (j'ai pas trop envie de péter mes données si jamais ça plante en plein traitement)
- dans mon fichier csv, si je veux insérer que les champs 4, 5 et 9, je spécifie ça comment dans le fichier de controle ?
 
merci [:pingouino]
 

Spoiler :

j'ai quasiment jamais utilisé ce soft [:petrus75]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-01-2006 à 23:31:28    

Harkonnen a écrit :


- dans mon fichier csv, si je veux insérer que les champs 4, 5 et 9, je spécifie ça comment dans le fichier de controle ?


je me réponds à moi même : il faut faire suivre toutes les colonnes que je ne veux pas insérer par le mot FILLER dans le fichier de controle
par contre, il ne semble pas possible de déclarer tout le chargement d'un fichier comme une seule transaction, ça craint du boudin [:pingouino]
je pense donc que j'importerais tout dans une table temporaire, et si j'ai aucun rejet, alors je ferais l'import réél


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-01-2006 à 23:51:44    

j'ai utilisé que ponctuellement, mais oui, il vaut mieux passer par une table temporaire sans aucune contrainte avec ce machin...[:petrus75]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed