Bonjour !

Merci de votre attention. Mon problème c'est que je n'arrive pas à entrer dans une boucle FOR LOOP (FOR i IN 1..nb_rows_report.COUNT
) lorsque je traite un fichier XML de plus de 10M. J'ai l'impression, avec la structure qui est utilisée dans le code ci-bas, que le fichier est trop gros et que le curseur est vide ! Lorsque j'utilise de plus petit fichier cela fonctionne très bien !

Voici un extrait d'une procédure qui extrait les informations du fichier XML et qui remplit quelques tables dans la base. J'ai remplacé le nom de certaines variables pour des raisons de sécurité, il faut surtout porter attention à la structure et non aux variables si jamais.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
 
   v_file                        XMLType;
   v_xml                        XMLType;
   reject_log                   EXCEPTION;
 
CURSOR cur_rec IS
     SELECT extractValue(value(LogRecord),'LogRecord/A') A,
             extractValue(value(LogRecord),'LogRecord/B') B,
             extractValue(value(LogRecord),'LogRecord/C') C,
             extractValue(value(LogRecord),'LogRecord/D') D,
             extractValue(value(LogRecord),'LogRecord/E') E,
             extractValue(value(LogRecord),'LogRecord/F') F,
             extractValue(value(LogRecord),'LogRecord/G') G,
          value(LogRecord) obj
        FROM table(XMLSequence(extract(v_xml, 'SignedLogs/Logs/LogRecord'))) LogRecord;
 
TYPE numtab IS TABLE OF cur_rec%ROWTYPE INDEX BY BINARY_INTEGER;
nb_rows_report              numtab;
nb_rows_limit                 PLS_INTEGER := 100;
 
   ---xsl transform to convert xml format to something more Oracle friendly ---
 
   v_xsl XMLType := XMLType('<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="/">
   <SignedLogs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ND1_2_0.xsd">
   <Header>
      <AA><xsl:value-of select="SignedLogs/Header/@AA" /></AA>
      <BB><xsl:value-of select="SignedLogs/Header/@BB" /></BB>
      <CC><xsl:value-of select="SignedLogs/Header/@CC" /></CC>
      <DD><xsl:value-of select="SignedLogs/Header/@DD" /></DD>
      <EE><xsl:value-of select="SignedLogs/Header/@EE" /></EE>
      <FF><xsl:value-of select="SignedLogs/Header/@FF" /></FF>
      <GG><xsl:value-of select="SignedLogs/Header/@GG" /></GG>
      <HH><xsl:value-of select="SignedLogs/Header/@HH" /></HH>
     <xsl:apply-templates select="SignedLogs/Header/error" />
   </Header>
 
   <Logs>
      <CreationDate><xsl:value-of select="SignedLogs/Logs/@CreationDate" /></CreationDate>
      <NumberOfRecords><xsl:value-of select="SignedLogs/Logs/@NumberOfRecords" /></NumberOfRecords>
     <xsl:apply-templates select="//LogRecord" />
   </Logs>
 
   </SignedLogs>
   </xsl:template>
 
 
   <xsl:template match="error">
      <error><xsl:value-of select="@id" /></error>
   </xsl:template>
 
 
   <xsl:template match="LogRecord">
      <LogRecord>
         <A><xsl:value-of select="@A" /></A>
         <B><xsl:value-of select="@B" /></B>
         <C><xsl:value-of select="@C" /></C>
         <D><xsl:value-of select="@D" /></D>
         <E><xsl:value-of select="@E" /></E>
         <F><xsl:value-of select="@F" /></F>
         <G><xsl:value-of select="@G" /></G>
        <xsl:apply-templates select="error" />
 
      </LogRecord>
   </xsl:template>
 
</xsl:stylesheet>');
 
BEGIN
 
   vo_ok := 0;
   vo_error_msg := ' ';
 
   --- Load log file ---
   v_file := xmltype(bfilename('DBXML',vi_filename),
                          nls_charset_id('AL32UTF8'));
 
 
   --- Transform XML to a more convenient format (ie putting data between
   ---                                   tags instead of within attributes ---
 
   v_xml := XMLType.transform(v_file, v_xsl);
 
 
   --- extract header info from loaded file ---
   SELECT extractValue(v_xml, '/SignedLogs/Header/AA'),
          extractValue(v_xml, '/SignedLogs/Header/BB'),
          extractValue(v_xml, '/SignedLogs/Header/CC'),
          extractValue(v_xml, '/SignedLogs/Header/DD'),
          extractValue(v_xml, '/SignedLogs/Header/EE'),
          extractValue(v_xml, '/SignedLogs/Header/FF'),
          extractValue(v_xml, '/SignedLogs/Header/GG'),
          extractValue(v_xml, '/SignedLogs/Header/HH'),
          extractValue(v_xml, '/SignedLogs/Logs/CreationDate'),
          extractValue(v_xml, '/SignedLogs/Logs/NumberOfRecords')
     INTO v_AA,
          v_BB,
          v_CC,
          v_DD,
          v_EE,
          v_FF,
          v_GG,
          v_HH,
          v_CreationDate,
          v_NumberOfRecords
     FROM dual;
 
   --- import header to db (no commit) ---
   insert_header(
      vi_AA           => v_AA,
      vi_BB           => v_BB,
      vi_CC           => v_CC,
      vi_DD           => v_DD,
      vi_EE           => v_EE,
      vi_FF           => v_FF,
      vi_GG          => v_GG,
      vi_path           => vi_filename,
      vi_creation_date  => TO_DATE(v_CreationDate,'YYYY/MM/DD HH24:MI'),
      vi_no_records     => v_NumberOfRecords,
      vi_errors                 => v_hdr_errors,
      vio_update_database       => v_update_database,
      vo_AA             => vo_AA,
      vo_BB             => v_BB,
      vo_CC            => v_CC,
      vo_DD            => v_DD,
      vo_EE            => v_EE,
      vo_FF           => v_FF,
      vo_ok                     => vo_ok,
      vo_error_num              => vo_error_num,
      vo_error_msg              => vo_error_msg);
 
 
   --- check for errors ---
   IF vo_ok <> 1 THEN
      RAISE reject_log;
   END IF;
 
  --- Extract log records ---
 
  OPEN cur_rec;
 
   LOOP
 
   FETCH cur_rec BULK COLLECT INTO nb_rows_report LIMIT nb_rows_limit;
 
          FOR i IN 1..nb_rows_report.COUNT 
 
                   LOOP
 
                   insert_detail(
                       vi_A           => vo_A,
                       vi_B           => v_B,
                       vi_C           => v_C,
                       vi_D           => v_D,
                       vi_E           => v_E,
                       vi_F           =>  nb_rows_report(i).A,
                       vi_errors     => v_det_errors,
                       vi_BB               => nb_rows_report(i).B,
                       vi_CC               => nb_rows_report(i).C,
                       vi_DD               => nb_rows_report(i).D,
                       vi_EE               => nb_rows_report(i).E,
                       vi_FF               => nb_rows_report(i).F,
                       vio_update_database     => v_update_database,
                       vo_ok                   => vo_ok,
                       vo_error_num            => vo_error_num,
                       vo_error_msg            => vo_error_msg);
 
 
                    --- check for errors ---
                    IF vo_ok <> 1 THEN
                       RAISE reject_log;
                    END IF;
 
 
                 END LOOP;
 
   EXIT WHEN cur_rec%NOTFOUND;  
 
   END LOOP;
 
   CLOSE cur_rec;
 
   --- commit both header and detail ---
   COMMIT;
   vo_ok := 1;
 
 
   --- error processing ---
   EXCEPTION
 
   --- log could not be imported ---
   WHEN reject_log THEN
      ROLLBACK;
 
 
   WHEN OTHERS THEN
      vo_error_msg := SUBSTR('Error processing xml: '||SQLERRM,1,200);
      vo_error_num := SQLCODE;
      ROLLBACK;
 
END;
Comment je peux vérifier que ma variable v_xml n'est pas vide ?

Merci.