Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Interfaces de programmation
Interfaces de programmation Forum d'entraide sur l'utilisation des API Oracle : Pré-compilateurs, OCI, OCCI, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/01/2011, 18h53   #1
Invité régulier
 
Inscription : août 2009
Messages : 12
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 12
Points : 8
Points : 8
Par défaut [OCILIB] Problème bizarre

J'ai un problème très bizarre avec OCILIB que je n'arrive pas a comprendre.

J'ai un serveur de bdd Oracle 10.2.0.3 sous AIX 5.3 en full 64 bit. Je le "bombarde" avec un binaire fonctionnant sous Windows XP Pro SP3 intégrant ocilib 3.8.1 telle que livrée.

Grosso modo je passe environ 60 fichiers sur les 1500 que je dois traiter. Puis plus une aucune ligne n'est insérée en base. Je n'ai aucune erreur. Le seul retour que j'ai c'est que "0 rows sont affectées sur les 1000 que contient le buffer binder au départ"...
Ce n'est pas un problème d'espace disque, ni d'extent, etc... J'ai tracé une des sessions Oracle sans plus de succès. Je vois les ordres d'insertion passer, aucune erreur n'est rapportée mais aucune ligne supplémentaire n'est insérée.

Fait intéressant, si je vide les tables et attaque à partir du 61ème fichier cela fonctionne puis à nouveau le même blocage plus loin sur la série... Comme s'il s'agissait d'un phénomène lié à un seuil en volume de données...

Le tablespace le + important:
Code :
1
2
3
TABLESPACE_NAME              BYTES     BLOCKS AUT   MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS                  
----------------------- ---------- ---------- --- ---------- ---------- ------------ ---------- -----------
DATA_WORK               2,4280E+10    2963816 YES 3,5184E+13 4294967293            1 2,4279E+10     2963800
La plus grosse des tables :
Code :
1
2
3
TABLESPACE           SEGMENT                               MBYTES      BLOCKS         EXTENTS        MAX_EXTENTS                    
-------------------- ------------------------------------- ----------- -------------- -------------- --------------                 
DATA_WORK       TABLE: HISTORIC_1164200782                   3207         410496             51     2147483645
J'ai également mis en doute la partie Windows, j'ai donc recompilé tout OCILIB et mon projet en 32 bits sur AIX 5.3 avec xlc v9 et Oracle 10.2.0.3. Même symptôme.

Cette situation évoque-t'elle quelque chose à quelqu'un?
jp_fan_2_C_linux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2011, 00h09   #2
Rédacteur/Modérateur
 
Avatar de Vincent Rogier
 
vincent rogier
Inscription : juillet 2007
Messages : 2 355
Détails du profil
Informations personnelles :
Nom : vincent rogier
Âge : 34

Informations forums :
Inscription : juillet 2007
Messages : 2 355
Points : 3 108
Points : 3 108
salut,

peux tu donner plus de précisions sur le code, les appels utilisés ?
__________________
Vincent Rogier.

Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

OCILIB (C Driver for Oracle)

Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle
Vincent Rogier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2011, 11h51   #3
Invité régulier
 
Inscription : août 2009
Messages : 12
Détails du profil
Informations personnelles :
Âge : 45
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 12
Points : 8
Points : 8
Par défaut Plus d'explications...

Bonjour,

Je vais essayer d'être le + concis possible! Le projet sur lequel je travaille consiste à charger dans une base de données une certaine quantité d'information. Comme indiqué dans mon message précédent le premier essai en grandeur réelle se fait avec un volume relativement restreint, de l'ordre de 600 Go au final.

Le programme a été développé en C++, il est fortement multithreadé pour optimiser le temps de chargement.

Le traitement d'insertion fonctionne de la manière suivante:
  • création d'un statement sur une des connexions disponibles dans un pool:
    Code :
    1
    2
    OCI_Statement *st = OCI_StatementCreate(Base::conn_pool[m_num_pool]);
    		IF ( st == NULL )...
    préparation du statement
    Code :
    1
    2
    iStmtActionRes = OCI_Prepare(st, m_buffer->GetSyntaxeInsert().c_str());
    		IF ( iStmtActionRes == FALSE )...
    réservation d'espace pour les data à insérer avec le statement (taille max = 1000 lignes)
    Code :
    1
    2
    	iStmtActionRes = OCI_BindArraySetSize(st, m_buffer->NombreLigne());
    		IF ( iStmtActionRes == FALSE )...
    pour chaque champ à insérer, et en fonction du type du champ (entier, string, date) on alloue un tableau de pointeur
    Code :
    1
    2
    3
    4
     
    int** buff_int = new int*[m_buffer->NombreChamps()];
    char** buff_char = new char*[m_buffer->NombreChamps()];
    char** buff_date = new char*[m_buffer->NombreChamps()];
    Chacun des tableaux est ensuite associé avec le statement
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    FOR ( int i = 0 ; i < m_buffer->NombreChamps() ; ++i )
    {
    	buff_int[i]  = NULL;
    	buff_char[i] = NULL;
    	buff_date[i] = NULL;
    	std::string type = ":" + m_buffer->NomChamps(i);
     
    	int* num = m_buffer->Int(m_buffer->NomChamps(i));
     	IF ( num != NULL )
    	{
    		buff_int[i] = num;
    		iStmtActionRes = OCI_BindArrayOfInts(st, type.c_str(), num, 0);
    		IF ( iStmtActionRes == FALSE )...
     
    	char* chaine = m_buffer->Char(m_buffer->NomChamps(i));
    	IF ( chaine != NULL )
    	{
    		buff_char[i] = chaine;
     
    		iStmtActionRes = OCI_BindArrayOfStrings(st, type.c_str(), chaine, m_buffer->TailleChar(m_buffer->NomChamps(i)), 0);
    		IF ( FALSE == iStmtActionRes )...
     
    	char* date = m_buffer->Date(m_buffer->NomChamps(i));
    	IF ( date != NULL )
    	{
    		buff_date[i] = date;
    		iStmtActionRes = OCI_BindArrayOfStrings(st, type.c_str(), date, m_buffer->TailleChar(m_buffer->NomChamps(i)), 0);
    		IF ( iStmtActionRes == FALSE )...
    Si tous les buffers sont correctement associés alors déclencher l'insertion
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    	IF ( bind_ok == true )
    	{
    		iNbRowsInArray = OCI_BindArrayGetSize(st);
    		DEBUG(m_nom) << "Insert <" << iNbRowsInArray << "> line in the table <" << m_buffer->NomTable() << ">" << print;
     
    		iStmtActionRes = OCI_Execute(st);
    		iAffectedRows = OCI_GetAffectedRows(st);
     
    		IF ( iStmtActionRes == FALSE )
    		{
    			ERREUR(m_nom) << "Affected rows <" << iAffectedRows << "> versus rows in buffer <" << iNbRowsInArray << ">" << print;
     
    			OCI_Error*	pErr = OCI_GetBatchError(st);
    			while ( pErr != NULL )
    			{
    				UNSIGNED int iRowIndex = OCI_ErrorGetRow(pErr);
    				IF ( 0 > iRowIndex )
    				{
    					ERREUR(m_nom) << "Error at row : <" << OCI_ErrorGetRow(pErr) << "> : <" << OCI_ErrorGetString(pErr) << ">" << print ;
    				}
    				else
    					ERREUR(m_nom) << "Error not related to array DML: " << OCI_ErrorGetString(pErr) << print ;
     
    				// Get next error
    				pErr = OCI_GetBatchError(st);
    			}
                    }
    		else IF ( iAffectedRows < iNbRowsInArray )
    		{
    			ERREUR(m_nom) << "Affected rows <" << iAffectedRows << "> versus rows in buffer <" << iNbRowsInArray << ">" << print;
    		}
    ...

Et comme indiqué dans mon message précédent, lorsque cela ne fonctionne pas, la fonction OCI_BindArrayGetSize(st) m'indique qu'un buffer de taille x a été correctement préparé, OCI_Execute(st) ne renvoie aucune erreur, tandis que la fonction OCI_GetAffectedRows(st) renvoie 0!
Je ne comprends pas...
jp_fan_2_C_linux est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h03.


 
 
 
 
Partenaires

Hébergement Web