~ubuntu-branches/ubuntu/precise/postgresql-9.1/precise-security

« back to all changes in this revision

Viewing changes to doc/src/sgml/html/ecpg-descriptors.html

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
2
<HTML
 
3
><HEAD
 
4
><TITLE
 
5
>Using Descriptor Areas</TITLE
 
6
><META
 
7
NAME="GENERATOR"
 
8
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
 
9
REV="MADE"
 
10
HREF="mailto:pgsql-docs@postgresql.org"><LINK
 
11
REL="HOME"
 
12
TITLE="PostgreSQL 9.1beta1 Documentation"
 
13
HREF="index.html"><LINK
 
14
REL="UP"
 
15
TITLE="ECPG - Embedded SQL in C"
 
16
HREF="ecpg.html"><LINK
 
17
REL="PREVIOUS"
 
18
TITLE="pgtypes Library"
 
19
HREF="ecpg-pgtypes.html"><LINK
 
20
REL="NEXT"
 
21
TITLE="Error Handling"
 
22
HREF="ecpg-errors.html"><LINK
 
23
REL="STYLESHEET"
 
24
TYPE="text/css"
 
25
HREF="stylesheet.css"><META
 
26
HTTP-EQUIV="Content-Type"
 
27
CONTENT="text/html; charset=ISO-8859-1"><META
 
28
NAME="creation"
 
29
CONTENT="2011-04-27T21:20:33"></HEAD
 
30
><BODY
 
31
CLASS="SECT1"
 
32
><DIV
 
33
CLASS="NAVHEADER"
 
34
><TABLE
 
35
SUMMARY="Header navigation table"
 
36
WIDTH="100%"
 
37
BORDER="0"
 
38
CELLPADDING="0"
 
39
CELLSPACING="0"
 
40
><TR
 
41
><TH
 
42
COLSPAN="5"
 
43
ALIGN="center"
 
44
VALIGN="bottom"
 
45
><A
 
46
HREF="index.html"
 
47
>PostgreSQL 9.1beta1 Documentation</A
 
48
></TH
 
49
></TR
 
50
><TR
 
51
><TD
 
52
WIDTH="10%"
 
53
ALIGN="left"
 
54
VALIGN="top"
 
55
><A
 
56
TITLE="pgtypes Library"
 
57
HREF="ecpg-pgtypes.html"
 
58
ACCESSKEY="P"
 
59
>Prev</A
 
60
></TD
 
61
><TD
 
62
WIDTH="10%"
 
63
ALIGN="left"
 
64
VALIGN="top"
 
65
><A
 
66
TITLE="ECPG - Embedded SQL in C"
 
67
HREF="ecpg.html"
 
68
>Fast Backward</A
 
69
></TD
 
70
><TD
 
71
WIDTH="60%"
 
72
ALIGN="center"
 
73
VALIGN="bottom"
 
74
>Chapter 33. <SPAN
 
75
CLASS="APPLICATION"
 
76
>ECPG</SPAN
 
77
> - Embedded <ACRONYM
 
78
CLASS="ACRONYM"
 
79
>SQL</ACRONYM
 
80
> in C</TD
 
81
><TD
 
82
WIDTH="10%"
 
83
ALIGN="right"
 
84
VALIGN="top"
 
85
><A
 
86
TITLE="ECPG - Embedded SQL in C"
 
87
HREF="ecpg.html"
 
88
>Fast Forward</A
 
89
></TD
 
90
><TD
 
91
WIDTH="10%"
 
92
ALIGN="right"
 
93
VALIGN="top"
 
94
><A
 
95
TITLE="Error Handling"
 
96
HREF="ecpg-errors.html"
 
97
ACCESSKEY="N"
 
98
>Next</A
 
99
></TD
 
100
></TR
 
101
></TABLE
 
102
><HR
 
103
ALIGN="LEFT"
 
104
WIDTH="100%"></DIV
 
105
><DIV
 
106
CLASS="SECT1"
 
107
><H1
 
108
CLASS="SECT1"
 
109
><A
 
110
NAME="ECPG-DESCRIPTORS"
 
111
>33.7. Using Descriptor Areas</A
 
112
></H1
 
113
><P
 
114
>   An SQL descriptor area is a more sophisticated method for processing
 
115
   the result of a <TT
 
116
CLASS="COMMAND"
 
117
>SELECT</TT
 
118
>, <TT
 
119
CLASS="COMMAND"
 
120
>FETCH</TT
 
121
> or
 
122
   a <TT
 
123
CLASS="COMMAND"
 
124
>DESCRIBE</TT
 
125
> statement. An SQL descriptor area groups
 
126
   the data of one row of data together with metadata items into one
 
127
   data structure.  The metadata is particularly useful when executing
 
128
   dynamic SQL statements, where the nature of the result columns might
 
129
   not be known ahead of time. PostgreSQL provides two ways to use
 
130
   Descriptor Areas: the named SQL Descriptor Areas and the C-structure
 
131
   SQLDAs.
 
132
  </P
 
133
><DIV
 
134
CLASS="SECT2"
 
135
><H2
 
136
CLASS="SECT2"
 
137
><A
 
138
NAME="ECPG-NAMED-DESCRIPTORS"
 
139
>33.7.1. Named SQL Descriptor Areas</A
 
140
></H2
 
141
><P
 
142
>    A named SQL descriptor area consists of a header, which contains
 
143
    information concerning the entire descriptor, and one or more item
 
144
    descriptor areas, which basically each describe one column in the
 
145
    result row.
 
146
   </P
 
147
><P
 
148
>    Before you can use an SQL descriptor area, you need to allocate one:
 
149
</P><PRE
 
150
CLASS="PROGRAMLISTING"
 
151
>EXEC SQL ALLOCATE DESCRIPTOR <TT
 
152
CLASS="REPLACEABLE"
 
153
><I
 
154
>identifier</I
 
155
></TT
 
156
>;</PRE
 
157
><P>
 
158
    The identifier serves as the <SPAN
 
159
CLASS="QUOTE"
 
160
>"variable name"</SPAN
 
161
> of the
 
162
    descriptor area.  
 
163
    When you don't need the descriptor anymore, you should deallocate
 
164
    it:
 
165
</P><PRE
 
166
CLASS="PROGRAMLISTING"
 
167
>EXEC SQL DEALLOCATE DESCRIPTOR <TT
 
168
CLASS="REPLACEABLE"
 
169
><I
 
170
>identifier</I
 
171
></TT
 
172
>;</PRE
 
173
><P>
 
174
   </P
 
175
><P
 
176
>    To use a descriptor area, specify it as the storage target in an
 
177
    <TT
 
178
CLASS="LITERAL"
 
179
>INTO</TT
 
180
> clause, instead of listing host variables:
 
181
</P><PRE
 
182
CLASS="PROGRAMLISTING"
 
183
>EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;</PRE
 
184
><P>
 
185
    If the result set is empty, the Descriptor Area will still contain
 
186
    the metadata from the query, i.e. the field names.
 
187
   </P
 
188
><P
 
189
>    For not yet executed prepared queries, the <TT
 
190
CLASS="COMMAND"
 
191
>DESCRIBE</TT
 
192
>
 
193
    statement can be used to get the metadata of the result set:
 
194
</P><PRE
 
195
CLASS="PROGRAMLISTING"
 
196
>EXEC SQL BEGIN DECLARE SECTION;
 
197
char *sql_stmt = "SELECT * FROM table1";
 
198
EXEC SQL END DECLARE SECTION;
 
199
 
 
200
EXEC SQL PREPARE stmt1 FROM :sql_stmt;
 
201
EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;</PRE
 
202
><P>
 
203
   </P
 
204
><P
 
205
>    Before PostgreSQL 9.0, the <TT
 
206
CLASS="LITERAL"
 
207
>SQL</TT
 
208
> keyword was optional,
 
209
    so using <TT
 
210
CLASS="LITERAL"
 
211
>DESCRIPTOR</TT
 
212
> and <TT
 
213
CLASS="LITERAL"
 
214
>SQL DESCRIPTOR</TT
 
215
>
 
216
    produced named SQL Descriptor Areas. Now it is mandatory, omitting
 
217
    the <TT
 
218
CLASS="LITERAL"
 
219
>SQL</TT
 
220
> keyword produces SQLDA Descriptor Areas,
 
221
    see <A
 
222
HREF="ecpg-descriptors.html#ECPG-SQLDA-DESCRIPTORS"
 
223
>Section 33.7.2</A
 
224
>.
 
225
   </P
 
226
><P
 
227
>    In <TT
 
228
CLASS="COMMAND"
 
229
>DESCRIBE</TT
 
230
> and <TT
 
231
CLASS="COMMAND"
 
232
>FETCH</TT
 
233
> statements,
 
234
    the <TT
 
235
CLASS="LITERAL"
 
236
>INTO</TT
 
237
> and <TT
 
238
CLASS="LITERAL"
 
239
>USING</TT
 
240
> keywords can be
 
241
    used to similarly: they produce the result set and the metadata in a
 
242
    Descriptor Area.
 
243
   </P
 
244
><P
 
245
>    Now how do you get the data out of the descriptor area?  You can
 
246
    think of the descriptor area as a structure with named fields.  To
 
247
    retrieve the value of a field from the header and store it into a
 
248
    host variable, use the following command:
 
249
</P><PRE
 
250
CLASS="PROGRAMLISTING"
 
251
>EXEC SQL GET DESCRIPTOR <TT
 
252
CLASS="REPLACEABLE"
 
253
><I
 
254
>name</I
 
255
></TT
 
256
> :<TT
 
257
CLASS="REPLACEABLE"
 
258
><I
 
259
>hostvar</I
 
260
></TT
 
261
> = <TT
 
262
CLASS="REPLACEABLE"
 
263
><I
 
264
>field</I
 
265
></TT
 
266
>;</PRE
 
267
><P>
 
268
    Currently, there is only one header field defined:
 
269
    <TT
 
270
CLASS="REPLACEABLE"
 
271
><I
 
272
>COUNT</I
 
273
></TT
 
274
>, which tells how many item
 
275
    descriptor areas exist (that is, how many columns are contained in
 
276
    the result).  The host variable needs to be of an integer type.  To
 
277
    get a field from the item descriptor area, use the following
 
278
    command:
 
279
</P><PRE
 
280
CLASS="PROGRAMLISTING"
 
281
>EXEC SQL GET DESCRIPTOR <TT
 
282
CLASS="REPLACEABLE"
 
283
><I
 
284
>name</I
 
285
></TT
 
286
> VALUE <TT
 
287
CLASS="REPLACEABLE"
 
288
><I
 
289
>num</I
 
290
></TT
 
291
> :<TT
 
292
CLASS="REPLACEABLE"
 
293
><I
 
294
>hostvar</I
 
295
></TT
 
296
> = <TT
 
297
CLASS="REPLACEABLE"
 
298
><I
 
299
>field</I
 
300
></TT
 
301
>;</PRE
 
302
><P>
 
303
    <TT
 
304
CLASS="REPLACEABLE"
 
305
><I
 
306
>num</I
 
307
></TT
 
308
> can be a literal integer or a host
 
309
    variable containing an integer. Possible fields are:
 
310
 
 
311
    <P
 
312
></P
 
313
></P><DIV
 
314
CLASS="VARIABLELIST"
 
315
><DL
 
316
><DT
 
317
><TT
 
318
CLASS="LITERAL"
 
319
>CARDINALITY</TT
 
320
> (integer)</DT
 
321
><DD
 
322
><P
 
323
>        number of rows in the result set
 
324
       </P
 
325
></DD
 
326
><DT
 
327
><TT
 
328
CLASS="LITERAL"
 
329
>DATA</TT
 
330
></DT
 
331
><DD
 
332
><P
 
333
>        actual data item (therefore, the data type of this field
 
334
        depends on the query)
 
335
       </P
 
336
></DD
 
337
><DT
 
338
><TT
 
339
CLASS="LITERAL"
 
340
>DATETIME_INTERVAL_CODE</TT
 
341
> (integer)</DT
 
342
><DD
 
343
><P
 
344
>        When <TT
 
345
CLASS="LITERAL"
 
346
>TYPE</TT
 
347
> is <TT
 
348
CLASS="LITERAL"
 
349
>9</TT
 
350
>,
 
351
        <TT
 
352
CLASS="LITERAL"
 
353
>DATETIME_INTERVAL_CODE</TT
 
354
> will have a value of
 
355
        <TT
 
356
CLASS="LITERAL"
 
357
>1</TT
 
358
> for <TT
 
359
CLASS="LITERAL"
 
360
>DATE</TT
 
361
>,
 
362
        <TT
 
363
CLASS="LITERAL"
 
364
>2</TT
 
365
> for <TT
 
366
CLASS="LITERAL"
 
367
>TIME</TT
 
368
>,
 
369
        <TT
 
370
CLASS="LITERAL"
 
371
>3</TT
 
372
> for <TT
 
373
CLASS="LITERAL"
 
374
>TIMESTAMP</TT
 
375
>,
 
376
        <TT
 
377
CLASS="LITERAL"
 
378
>4</TT
 
379
> for <TT
 
380
CLASS="LITERAL"
 
381
>TIME WITH TIME ZONE</TT
 
382
>, or
 
383
        <TT
 
384
CLASS="LITERAL"
 
385
>5</TT
 
386
> for <TT
 
387
CLASS="LITERAL"
 
388
>TIMESTAMP WITH TIME ZONE</TT
 
389
>.
 
390
       </P
 
391
></DD
 
392
><DT
 
393
><TT
 
394
CLASS="LITERAL"
 
395
>DATETIME_INTERVAL_PRECISION</TT
 
396
> (integer)</DT
 
397
><DD
 
398
><P
 
399
>        not implemented
 
400
       </P
 
401
></DD
 
402
><DT
 
403
><TT
 
404
CLASS="LITERAL"
 
405
>INDICATOR</TT
 
406
> (integer)</DT
 
407
><DD
 
408
><P
 
409
>        the indicator (indicating a null value or a value truncation)
 
410
       </P
 
411
></DD
 
412
><DT
 
413
><TT
 
414
CLASS="LITERAL"
 
415
>KEY_MEMBER</TT
 
416
> (integer)</DT
 
417
><DD
 
418
><P
 
419
>        not implemented
 
420
       </P
 
421
></DD
 
422
><DT
 
423
><TT
 
424
CLASS="LITERAL"
 
425
>LENGTH</TT
 
426
> (integer)</DT
 
427
><DD
 
428
><P
 
429
>        length of the datum in characters
 
430
       </P
 
431
></DD
 
432
><DT
 
433
><TT
 
434
CLASS="LITERAL"
 
435
>NAME</TT
 
436
> (string)</DT
 
437
><DD
 
438
><P
 
439
>        name of the column
 
440
       </P
 
441
></DD
 
442
><DT
 
443
><TT
 
444
CLASS="LITERAL"
 
445
>NULLABLE</TT
 
446
> (integer)</DT
 
447
><DD
 
448
><P
 
449
>        not implemented
 
450
       </P
 
451
></DD
 
452
><DT
 
453
><TT
 
454
CLASS="LITERAL"
 
455
>OCTET_LENGTH</TT
 
456
> (integer)</DT
 
457
><DD
 
458
><P
 
459
>        length of the character representation of the datum in bytes
 
460
       </P
 
461
></DD
 
462
><DT
 
463
><TT
 
464
CLASS="LITERAL"
 
465
>PRECISION</TT
 
466
> (integer)</DT
 
467
><DD
 
468
><P
 
469
>        precision (for type <TT
 
470
CLASS="TYPE"
 
471
>numeric</TT
 
472
>)
 
473
       </P
 
474
></DD
 
475
><DT
 
476
><TT
 
477
CLASS="LITERAL"
 
478
>RETURNED_LENGTH</TT
 
479
> (integer)</DT
 
480
><DD
 
481
><P
 
482
>        length of the datum in characters
 
483
       </P
 
484
></DD
 
485
><DT
 
486
><TT
 
487
CLASS="LITERAL"
 
488
>RETURNED_OCTET_LENGTH</TT
 
489
> (integer)</DT
 
490
><DD
 
491
><P
 
492
>        length of the character representation of the datum in bytes
 
493
       </P
 
494
></DD
 
495
><DT
 
496
><TT
 
497
CLASS="LITERAL"
 
498
>SCALE</TT
 
499
> (integer)</DT
 
500
><DD
 
501
><P
 
502
>        scale (for type <TT
 
503
CLASS="TYPE"
 
504
>numeric</TT
 
505
>)
 
506
       </P
 
507
></DD
 
508
><DT
 
509
><TT
 
510
CLASS="LITERAL"
 
511
>TYPE</TT
 
512
> (integer)</DT
 
513
><DD
 
514
><P
 
515
>        numeric code of the data type of the column
 
516
       </P
 
517
></DD
 
518
></DL
 
519
></DIV
 
520
><P>
 
521
   </P
 
522
><P
 
523
>    In <TT
 
524
CLASS="COMMAND"
 
525
>EXECUTE</TT
 
526
>, <TT
 
527
CLASS="COMMAND"
 
528
>DECLARE</TT
 
529
> and <TT
 
530
CLASS="COMMAND"
 
531
>OPEN</TT
 
532
>
 
533
    statements, the effect of the <TT
 
534
CLASS="LITERAL"
 
535
>INTO</TT
 
536
> and <TT
 
537
CLASS="LITERAL"
 
538
>USING</TT
 
539
>
 
540
    keywords are different. A Descriptor Area can also be manually built to
 
541
    provide the input parameters for a query or a cursor and
 
542
    <TT
 
543
CLASS="LITERAL"
 
544
>USING SQL DESCRIPTOR <TT
 
545
CLASS="REPLACEABLE"
 
546
><I
 
547
>name</I
 
548
></TT
 
549
></TT
 
550
>
 
551
    is the way to pass the input parameters into a parametrized query. The statement
 
552
    to build a named SQL Descriptor Area is below:
 
553
</P><PRE
 
554
CLASS="PROGRAMLISTING"
 
555
>EXEC SQL SET DESCRIPTOR <TT
 
556
CLASS="REPLACEABLE"
 
557
><I
 
558
>name</I
 
559
></TT
 
560
> VALUE <TT
 
561
CLASS="REPLACEABLE"
 
562
><I
 
563
>num</I
 
564
></TT
 
565
> <TT
 
566
CLASS="REPLACEABLE"
 
567
><I
 
568
>field</I
 
569
></TT
 
570
> = :<TT
 
571
CLASS="REPLACEABLE"
 
572
><I
 
573
>hostvar</I
 
574
></TT
 
575
>;</PRE
 
576
><P>
 
577
   </P
 
578
><P
 
579
>    PostgreSQL supports retrieving more that one record in one <TT
 
580
CLASS="COMMAND"
 
581
>FETCH</TT
 
582
>
 
583
    statement and storing the data in host variables in this case assumes that the
 
584
    variable is an array. E.g.:
 
585
</P><PRE
 
586
CLASS="PROGRAMLISTING"
 
587
>EXEC SQL BEGIN DECLARE SECTION;
 
588
int id[5];
 
589
EXEC SQL END DECLARE SECTION;
 
590
 
 
591
EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc;
 
592
 
 
593
EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;</PRE
 
594
><P>
 
595
 
 
596
   </P
 
597
></DIV
 
598
><DIV
 
599
CLASS="SECT2"
 
600
><H2
 
601
CLASS="SECT2"
 
602
><A
 
603
NAME="ECPG-SQLDA-DESCRIPTORS"
 
604
>33.7.2. SQLDA Descriptor Areas</A
 
605
></H2
 
606
><P
 
607
>    An SQLDA Descriptor Area is a C language structure which can be also used
 
608
    to get the result set and the metadata of a query. One structure stores one
 
609
    record from the result set.
 
610
</P><PRE
 
611
CLASS="PROGRAMLISTING"
 
612
>EXEC SQL include sqlda.h;
 
613
sqlda_t         *mysqlda;
 
614
 
 
615
EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;</PRE
 
616
><P>
 
617
    Note that the <TT
 
618
CLASS="LITERAL"
 
619
>SQL</TT
 
620
> keyword is omitted. The paragraphs about
 
621
    the use cases of the <TT
 
622
CLASS="LITERAL"
 
623
>INTO</TT
 
624
> and <TT
 
625
CLASS="LITERAL"
 
626
>USING</TT
 
627
>
 
628
    keywords in <A
 
629
HREF="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS"
 
630
>Section 33.7.1</A
 
631
> also apply here with an addition.
 
632
    In a <TT
 
633
CLASS="COMMAND"
 
634
>DESCRIBE</TT
 
635
> statement the <TT
 
636
CLASS="LITERAL"
 
637
>DESCRIPTOR</TT
 
638
>
 
639
    keyword can be completely omitted if the <TT
 
640
CLASS="LITERAL"
 
641
>INTO</TT
 
642
> keyword is used:
 
643
</P><PRE
 
644
CLASS="PROGRAMLISTING"
 
645
>EXEC SQL DESCRIBE prepared_statement INTO mysqlda;</PRE
 
646
><P>
 
647
   </P
 
648
><DIV
 
649
CLASS="PROCEDURE"
 
650
><P
 
651
>      The general flow of a program that uses SQLDA is:
 
652
     </P
 
653
><OL
 
654
TYPE="1"
 
655
><LI
 
656
CLASS="STEP"
 
657
><P
 
658
>Prepare a query, and declare a cursor for it.</P
 
659
></LI
 
660
><LI
 
661
CLASS="STEP"
 
662
><P
 
663
>Declare an SQLDA for the result rows.</P
 
664
></LI
 
665
><LI
 
666
CLASS="STEP"
 
667
><P
 
668
>Declare an SQLDA for the input parameters, and initialize them (memory allocation, parameter settings).</P
 
669
></LI
 
670
><LI
 
671
CLASS="STEP"
 
672
><P
 
673
>Open a cursor with the input SQLDA.</P
 
674
></LI
 
675
><LI
 
676
CLASS="STEP"
 
677
><P
 
678
>Fetch rows from the cursor, and store them into an output SQLDA.</P
 
679
></LI
 
680
><LI
 
681
CLASS="STEP"
 
682
><P
 
683
>Read values from the output SQLDA into the host variables (with conversion if necessary).</P
 
684
></LI
 
685
><LI
 
686
CLASS="STEP"
 
687
><P
 
688
>Close the cursor.</P
 
689
></LI
 
690
><LI
 
691
CLASS="STEP"
 
692
><P
 
693
>Free the memory area allocated for the input SQLDA.</P
 
694
></LI
 
695
></OL
 
696
></DIV
 
697
><DIV
 
698
CLASS="SECT3"
 
699
><H3
 
700
CLASS="SECT3"
 
701
><A
 
702
NAME="AEN41933"
 
703
>33.7.2.1. SQLDA Datac Structure</A
 
704
></H3
 
705
><P
 
706
>     SQLDA uses three data structure
 
707
     types: <TT
 
708
CLASS="TYPE"
 
709
>sqlda_t</TT
 
710
>, <TT
 
711
CLASS="TYPE"
 
712
>sqlvar_t</TT
 
713
>,
 
714
     and <TT
 
715
CLASS="TYPE"
 
716
>struct sqlname</TT
 
717
>.
 
718
    </P
 
719
><DIV
 
720
CLASS="TIP"
 
721
><BLOCKQUOTE
 
722
CLASS="TIP"
 
723
><P
 
724
><B
 
725
>Tip: </B
 
726
>      PostgreSQL's SQLDA has a similar data structure to the one in
 
727
      IBM DB2 Universal Database, so some technical information on
 
728
      DB2's SQLDA could help understanding PostgreSQL's one better.
 
729
     </P
 
730
></BLOCKQUOTE
 
731
></DIV
 
732
><DIV
 
733
CLASS="SECT4"
 
734
><H4
 
735
CLASS="SECT4"
 
736
><A
 
737
NAME="ECPG-SQLDA-SQLDA"
 
738
>33.7.2.1.1. sqlda_t Structure</A
 
739
></H4
 
740
><P
 
741
>      The structure type <TT
 
742
CLASS="TYPE"
 
743
>sqlda_t</TT
 
744
> is the type of the
 
745
      actual SQLDA.  It holds one record.  And two or
 
746
      more <TT
 
747
CLASS="TYPE"
 
748
>sqlda_t</TT
 
749
> structures can be connected in a
 
750
      linked list with the pointer in
 
751
      the <TT
 
752
CLASS="STRUCTFIELD"
 
753
>desc_next</TT
 
754
> field, thus
 
755
      representing an ordered collection of rows.  So, when two or
 
756
      more rows are fetched, the application can read them by
 
757
      following the <TT
 
758
CLASS="STRUCTFIELD"
 
759
>desc_next</TT
 
760
> pointer in
 
761
      each <TT
 
762
CLASS="TYPE"
 
763
>sqlda_t</TT
 
764
> node.
 
765
     </P
 
766
><P
 
767
>      The definition of <TT
 
768
CLASS="TYPE"
 
769
>sqlda_t</TT
 
770
> is:
 
771
</P><PRE
 
772
CLASS="PROGRAMLISTING"
 
773
>struct sqlda_struct
 
774
{
 
775
    char            sqldaid[8];
 
776
    long            sqldabc;
 
777
    short           sqln;
 
778
    short           sqld;
 
779
    struct sqlda_struct *desc_next;
 
780
    struct sqlvar_struct sqlvar[1];
 
781
};
 
782
 
 
783
typedef struct sqlda_struct sqlda_t;</PRE
 
784
><P>
 
785
 
 
786
      The meaning of the fields is:
 
787
 
 
788
    <P
 
789
></P
 
790
></P><DIV
 
791
CLASS="VARIABLELIST"
 
792
><DL
 
793
><DT
 
794
><TT
 
795
CLASS="LITERAL"
 
796
>sqldaid</TT
 
797
></DT
 
798
><DD
 
799
><P
 
800
>        It contains the literal string <TT
 
801
CLASS="LITERAL"
 
802
>"SQLDA  "</TT
 
803
>.
 
804
       </P
 
805
></DD
 
806
><DT
 
807
><TT
 
808
CLASS="LITERAL"
 
809
>sqldabc</TT
 
810
></DT
 
811
><DD
 
812
><P
 
813
>        It contains the size of the allocated space in bytes.
 
814
       </P
 
815
></DD
 
816
><DT
 
817
><TT
 
818
CLASS="LITERAL"
 
819
>sqln</TT
 
820
></DT
 
821
><DD
 
822
><P
 
823
>        It contains the number of input parameters for a parametrized query
 
824
        case it's passed into <TT
 
825
CLASS="COMMAND"
 
826
>OPEN</TT
 
827
>, <TT
 
828
CLASS="COMMAND"
 
829
>DECLARE</TT
 
830
> or
 
831
        <TT
 
832
CLASS="COMMAND"
 
833
>EXECUTE</TT
 
834
> statements using the <TT
 
835
CLASS="LITERAL"
 
836
>USING</TT
 
837
>
 
838
        keyword. In case it's used as output of <TT
 
839
CLASS="COMMAND"
 
840
>SELECT</TT
 
841
>,
 
842
        <TT
 
843
CLASS="COMMAND"
 
844
>EXECUTE</TT
 
845
> or <TT
 
846
CLASS="COMMAND"
 
847
>FETCH</TT
 
848
> statements,
 
849
        its value is the same as <TT
 
850
CLASS="LITERAL"
 
851
>sqld</TT
 
852
>
 
853
        statement
 
854
       </P
 
855
></DD
 
856
><DT
 
857
><TT
 
858
CLASS="LITERAL"
 
859
>sqld</TT
 
860
></DT
 
861
><DD
 
862
><P
 
863
>        It contains the number of fields in a result set.
 
864
       </P
 
865
></DD
 
866
><DT
 
867
><TT
 
868
CLASS="LITERAL"
 
869
>desc_next</TT
 
870
></DT
 
871
><DD
 
872
><P
 
873
>        If the query returns more than one records, multiple linked SQLDA structures
 
874
        are returned, the first record is stored in the SQLDA returned in the
 
875
       </P
 
876
></DD
 
877
><DT
 
878
><TT
 
879
CLASS="LITERAL"
 
880
>sqlvar</TT
 
881
></DT
 
882
><DD
 
883
><P
 
884
>        This is the array of the columns in the result set.
 
885
       </P
 
886
></DD
 
887
></DL
 
888
></DIV
 
889
><P>
 
890
     </P
 
891
></DIV
 
892
><DIV
 
893
CLASS="SECT4"
 
894
><H4
 
895
CLASS="SECT4"
 
896
><A
 
897
NAME="ECPG-SQLDA-SQLVAR"
 
898
>33.7.2.1.2. sqlvar_t Structure</A
 
899
></H4
 
900
><P
 
901
>      The structure type <TT
 
902
CLASS="TYPE"
 
903
>sqlvar_t</TT
 
904
> holds a column value
 
905
      and metadata such as type and length. The definition of the type
 
906
      is:
 
907
 
 
908
</P><PRE
 
909
CLASS="PROGRAMLISTING"
 
910
>struct sqlvar_struct
 
911
{
 
912
    short          sqltype;
 
913
    short          sqllen;
 
914
    char          *sqldata;
 
915
    short         *sqlind;
 
916
    struct sqlname sqlname;
 
917
};
 
918
 
 
919
typedef struct sqlvar_struct sqlvar_t;</PRE
 
920
><P>
 
921
 
 
922
      The meaning of the fields is:
 
923
 
 
924
        <P
 
925
></P
 
926
></P><DIV
 
927
CLASS="VARIABLELIST"
 
928
><DL
 
929
><DT
 
930
><TT
 
931
CLASS="LITERAL"
 
932
>sqltype</TT
 
933
></DT
 
934
><DD
 
935
><P
 
936
>            Contains the type identifier of the field. For values,
 
937
            see <TT
 
938
CLASS="LITERAL"
 
939
>enum ECPGttype</TT
 
940
> in <TT
 
941
CLASS="LITERAL"
 
942
>ecpgtype.h</TT
 
943
>.
 
944
           </P
 
945
></DD
 
946
><DT
 
947
><TT
 
948
CLASS="LITERAL"
 
949
>sqllen</TT
 
950
></DT
 
951
><DD
 
952
><P
 
953
>            Contains the binary length of the field. e.g. 4 bytes for <TT
 
954
CLASS="TYPE"
 
955
>ECPGt_int</TT
 
956
>.
 
957
           </P
 
958
></DD
 
959
><DT
 
960
><TT
 
961
CLASS="LITERAL"
 
962
>sqldata</TT
 
963
></DT
 
964
><DD
 
965
><P
 
966
>            Points to the data.  The format of the data is described
 
967
            in <A
 
968
HREF="ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING"
 
969
>Section 33.4.4</A
 
970
>.
 
971
           </P
 
972
></DD
 
973
><DT
 
974
><TT
 
975
CLASS="LITERAL"
 
976
>sqlind</TT
 
977
></DT
 
978
><DD
 
979
><P
 
980
>            Points to the null indicator.  0 means not null, -1 means
 
981
            null.
 
982
           </P
 
983
></DD
 
984
><DT
 
985
><TT
 
986
CLASS="LITERAL"
 
987
>sqlname</TT
 
988
></DT
 
989
><DD
 
990
><P
 
991
>            The the name of the field.
 
992
           </P
 
993
></DD
 
994
></DL
 
995
></DIV
 
996
><P>
 
997
     </P
 
998
></DIV
 
999
><DIV
 
1000
CLASS="SECT4"
 
1001
><H4
 
1002
CLASS="SECT4"
 
1003
><A
 
1004
NAME="ECPG-SQLDA-SQLNAME"
 
1005
>33.7.2.1.3. struct sqlname Structure</A
 
1006
></H4
 
1007
><P
 
1008
>      A <TT
 
1009
CLASS="TYPE"
 
1010
>struct sqlname</TT
 
1011
> structure holds a column name.  It
 
1012
      is used as a member of the <TT
 
1013
CLASS="TYPE"
 
1014
>sqlvar_t</TT
 
1015
> structure.  The
 
1016
      definition of the structure is:
 
1017
</P><PRE
 
1018
CLASS="PROGRAMLISTING"
 
1019
>#define NAMEDATALEN 64
 
1020
 
 
1021
struct sqlname
 
1022
{
 
1023
        short           length;
 
1024
        char            data[NAMEDATALEN];
 
1025
};</PRE
 
1026
><P>
 
1027
      The meaning of the fields is:
 
1028
            <P
 
1029
></P
 
1030
></P><DIV
 
1031
CLASS="VARIABLELIST"
 
1032
><DL
 
1033
><DT
 
1034
><TT
 
1035
CLASS="LITERAL"
 
1036
>length</TT
 
1037
></DT
 
1038
><DD
 
1039
><P
 
1040
>                 Contains the length of the field name.
 
1041
                </P
 
1042
></DD
 
1043
><DT
 
1044
><TT
 
1045
CLASS="LITERAL"
 
1046
>data</TT
 
1047
></DT
 
1048
><DD
 
1049
><P
 
1050
>                 Contains the actual field name.
 
1051
                </P
 
1052
></DD
 
1053
></DL
 
1054
></DIV
 
1055
><P>
 
1056
     </P
 
1057
></DIV
 
1058
></DIV
 
1059
><DIV
 
1060
CLASS="SECT3"
 
1061
><H3
 
1062
CLASS="SECT3"
 
1063
><A
 
1064
NAME="ECPG-SQLDA-OUTPUT"
 
1065
>33.7.2.2. Retreiving a Result Set Using an SQLDA</A
 
1066
></H3
 
1067
><DIV
 
1068
CLASS="PROCEDURE"
 
1069
><P
 
1070
>      The general steps to retrieve a query result set through an
 
1071
      SQLDA are:
 
1072
     </P
 
1073
><OL
 
1074
TYPE="1"
 
1075
><LI
 
1076
CLASS="STEP"
 
1077
><P
 
1078
>Declare an <TT
 
1079
CLASS="TYPE"
 
1080
>sqlda_t</TT
 
1081
> structure to receive the result set.</P
 
1082
></LI
 
1083
><LI
 
1084
CLASS="STEP"
 
1085
><P
 
1086
>Execute <TT
 
1087
CLASS="COMMAND"
 
1088
>FETCH</TT
 
1089
>/<TT
 
1090
CLASS="COMMAND"
 
1091
>EXECUTE</TT
 
1092
>/<TT
 
1093
CLASS="COMMAND"
 
1094
>DESCRIBE</TT
 
1095
> commands to process a query specifying the declared SQLDA.</P
 
1096
></LI
 
1097
><LI
 
1098
CLASS="STEP"
 
1099
><P
 
1100
>Check the number of records in the result set by looking at <TT
 
1101
CLASS="STRUCTFIELD"
 
1102
>sqln</TT
 
1103
>, a member of the <TT
 
1104
CLASS="TYPE"
 
1105
>sqlda_t</TT
 
1106
> structure.</P
 
1107
></LI
 
1108
><LI
 
1109
CLASS="STEP"
 
1110
><P
 
1111
>Get the values of each column from <TT
 
1112
CLASS="LITERAL"
 
1113
>sqlvar[0]</TT
 
1114
>, <TT
 
1115
CLASS="LITERAL"
 
1116
>sqlvar[1]</TT
 
1117
>, etc., members of the <TT
 
1118
CLASS="TYPE"
 
1119
>sqlda_t</TT
 
1120
> structure.</P
 
1121
></LI
 
1122
><LI
 
1123
CLASS="STEP"
 
1124
><P
 
1125
>Go to next row (<TT
 
1126
CLASS="TYPE"
 
1127
>sqlda_t</TT
 
1128
> structure) by following the <TT
 
1129
CLASS="STRUCTFIELD"
 
1130
>desc_next</TT
 
1131
> pointer, a member of the <TT
 
1132
CLASS="TYPE"
 
1133
>sqlda_t</TT
 
1134
> structure.</P
 
1135
></LI
 
1136
><LI
 
1137
CLASS="STEP"
 
1138
><P
 
1139
>Repeat above as you need.</P
 
1140
></LI
 
1141
></OL
 
1142
></DIV
 
1143
><P
 
1144
>     Here is an example retrieving a result set through an SQLDA.
 
1145
    </P
 
1146
><P
 
1147
>     First, declare a <TT
 
1148
CLASS="TYPE"
 
1149
>sqlda_t</TT
 
1150
> structure to receive the result set.
 
1151
</P><PRE
 
1152
CLASS="PROGRAMLISTING"
 
1153
>sqlda_t *sqlda1;</PRE
 
1154
><P>
 
1155
    </P
 
1156
><P
 
1157
>     Next, specify the SQLDA in a command.  This is
 
1158
     a <TT
 
1159
CLASS="COMMAND"
 
1160
>FETCH</TT
 
1161
> command example.
 
1162
</P><PRE
 
1163
CLASS="PROGRAMLISTING"
 
1164
>EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;</PRE
 
1165
><P>
 
1166
    </P
 
1167
><P
 
1168
>     Run a loop following the linked list to retrieve the rows.
 
1169
</P><PRE
 
1170
CLASS="PROGRAMLISTING"
 
1171
>sqlda_t *cur_sqlda;
 
1172
 
 
1173
for (cur_sqlda = sqlda1;
 
1174
     cur_sqlda != NULL;
 
1175
     cur_sqlda = cur_sqlda-&#62;desc_next)
 
1176
{
 
1177
    ...
 
1178
}</PRE
 
1179
><P>
 
1180
    </P
 
1181
><P
 
1182
>     Inside the loop, run another loop to retrieve each column data
 
1183
     (<TT
 
1184
CLASS="TYPE"
 
1185
>sqlvar_t</TT
 
1186
> structure) of the row.
 
1187
</P><PRE
 
1188
CLASS="PROGRAMLISTING"
 
1189
>for (i = 0; i &lt; cur_sqlda-&#62;sqld; i++)
 
1190
{
 
1191
    sqlvar_t v = cur_sqlda-&#62;sqlvar[i];
 
1192
    char *sqldata = v.sqldata;
 
1193
    short sqllen  = v.sqllen;
 
1194
    ...
 
1195
}</PRE
 
1196
><P>
 
1197
    </P
 
1198
><P
 
1199
>     To get a column value, check the <TT
 
1200
CLASS="STRUCTFIELD"
 
1201
>sqltype</TT
 
1202
> value,
 
1203
     a member of the <TT
 
1204
CLASS="TYPE"
 
1205
>sqlvar_t</TT
 
1206
> structure.  Then, switch
 
1207
     to an appropriate way, depending on the column type, to copy
 
1208
     data from the <TT
 
1209
CLASS="STRUCTFIELD"
 
1210
>sqlvar</TT
 
1211
> field to a host variable.
 
1212
</P><PRE
 
1213
CLASS="PROGRAMLISTING"
 
1214
>char var_buf[1024];
 
1215
 
 
1216
switch (v.sqltype)
 
1217
{
 
1218
    case ECPGt_char:
 
1219
        memset(&amp;var_buf, 0, sizeof(var_buf));
 
1220
        memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &#60;= sqllen ? sizeof(var_buf) - 1 : sqllen));
 
1221
        break;
 
1222
 
 
1223
    case ECPGt_int: /* integer */
 
1224
        memcpy(&amp;intval, sqldata, sqllen);
 
1225
        snprintf(var_buf, sizeof(var_buf), "%d", intval);
 
1226
        break;
 
1227
 
 
1228
    ...
 
1229
}</PRE
 
1230
><P>
 
1231
    </P
 
1232
></DIV
 
1233
><DIV
 
1234
CLASS="SECT3"
 
1235
><H3
 
1236
CLASS="SECT3"
 
1237
><A
 
1238
NAME="ECPG-SQLDA-INPUT"
 
1239
>33.7.2.3. Passing Query Parameters Using an SQLDA</A
 
1240
></H3
 
1241
><DIV
 
1242
CLASS="PROCEDURE"
 
1243
><P
 
1244
>      The general steps to use an SQLDA to pass input
 
1245
      parameters to a prepared query are:
 
1246
     </P
 
1247
><OL
 
1248
TYPE="1"
 
1249
><LI
 
1250
CLASS="STEP"
 
1251
><P
 
1252
>Create a prepared query (prepared statement)</P
 
1253
></LI
 
1254
><LI
 
1255
CLASS="STEP"
 
1256
><P
 
1257
>Declare a sqlda_t structure as an input SQLDA.</P
 
1258
></LI
 
1259
><LI
 
1260
CLASS="STEP"
 
1261
><P
 
1262
>Allocate memory area (as sqlda_t structure) for the input SQLDA.</P
 
1263
></LI
 
1264
><LI
 
1265
CLASS="STEP"
 
1266
><P
 
1267
>Set (copy) input values in the allocated memory.</P
 
1268
></LI
 
1269
><LI
 
1270
CLASS="STEP"
 
1271
><P
 
1272
>Open a cursor with specifying the input SQLDA.</P
 
1273
></LI
 
1274
></OL
 
1275
></DIV
 
1276
><P
 
1277
>     Here is an example.
 
1278
    </P
 
1279
><P
 
1280
>     First, create a prepared statement.
 
1281
</P><PRE
 
1282
CLASS="PROGRAMLISTING"
 
1283
>EXEC SQL BEGIN DECLARE SECTION;
 
1284
char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)";
 
1285
EXEC SQL END DECLARE SECTION;
 
1286
 
 
1287
EXEC SQL PREPARE stmt1 FROM :query;</PRE
 
1288
><P>
 
1289
    </P
 
1290
><P
 
1291
>     Next, allocate memory for an SQLDA, and set the number of input
 
1292
     parameters in <TT
 
1293
CLASS="STRUCTFIELD"
 
1294
>sqln</TT
 
1295
>, a member variable of
 
1296
     the <TT
 
1297
CLASS="TYPE"
 
1298
>sqlda_t</TT
 
1299
> structure.  When two or more input
 
1300
     parameters are required for the prepared query, the application
 
1301
     has to allocate additional memory space which is calculated by
 
1302
     (nr. of params - 1) * sizeof(sqlvar_t).  The example shown here
 
1303
     allocates memory space for two input parameters.
 
1304
</P><PRE
 
1305
CLASS="PROGRAMLISTING"
 
1306
>sqlda_t *sqlda2;
 
1307
 
 
1308
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1309
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1310
 
 
1311
sqlda2-&#62;sqln = 2; /* number of input variables */</PRE
 
1312
><P>
 
1313
    </P
 
1314
><P
 
1315
>     After memory allocation, store the parameter values into the
 
1316
     <TT
 
1317
CLASS="LITERAL"
 
1318
>sqlvar[]</TT
 
1319
> array.  (This is same array used for
 
1320
     retrieving column values when the SQLDA is receiving a result
 
1321
     set.)  In this example, the input parameters
 
1322
     are <TT
 
1323
CLASS="LITERAL"
 
1324
>"postgres"</TT
 
1325
>, having a string type,
 
1326
     and <TT
 
1327
CLASS="LITERAL"
 
1328
>1</TT
 
1329
>, having an integer type.
 
1330
</P><PRE
 
1331
CLASS="PROGRAMLISTING"
 
1332
>sqlda2-&#62;sqlvar[0].sqltype = ECPGt_char;
 
1333
sqlda2-&#62;sqlvar[0].sqldata = "postgres";
 
1334
sqlda2-&#62;sqlvar[0].sqllen  = 8;
 
1335
 
 
1336
int intval = 1;
 
1337
sqlda2-&#62;sqlvar[1].sqltype = ECPGt_int;
 
1338
sqlda2-&#62;sqlvar[1].sqldata = (char *) &amp;intval;
 
1339
sqlda2-&#62;sqlvar[1].sqllen  = sizeof(intval);</PRE
 
1340
><P>
 
1341
    </P
 
1342
><P
 
1343
>     By opening a cursor and specifying the SQLDA that was set up
 
1344
     beforehand, the input parameters are passed to the prepared
 
1345
     statement.
 
1346
</P><PRE
 
1347
CLASS="PROGRAMLISTING"
 
1348
>EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;</PRE
 
1349
><P>
 
1350
    </P
 
1351
><P
 
1352
>     Finally, after using input SQLDAs, the allocated memory space
 
1353
     must be freed explicitly, unlike SQLDAs used for receiving query
 
1354
     results.
 
1355
</P><PRE
 
1356
CLASS="PROGRAMLISTING"
 
1357
>free(sqlda2);</PRE
 
1358
><P>
 
1359
    </P
 
1360
></DIV
 
1361
><DIV
 
1362
CLASS="SECT3"
 
1363
><H3
 
1364
CLASS="SECT3"
 
1365
><A
 
1366
NAME="ECPG-SQLDA-EXAMPLE"
 
1367
>33.7.2.4. A Sample Application Using SQLDA</A
 
1368
></H3
 
1369
><P
 
1370
>     Here is an example program, which describes how to fetch access
 
1371
     statistics of the databases, specified by the input parameters,
 
1372
     from the system catalogs.
 
1373
    </P
 
1374
><P
 
1375
>     This application joins two system tables, pg_database and
 
1376
     pg_stat_database on the database oid, and also fetches and shows
 
1377
     the database statistics which are retreived by two input
 
1378
     parameters (a database "postgres", and oid "1").
 
1379
    </P
 
1380
><P
 
1381
>     First, declare an SQLDA for input and an SQLDA for output.
 
1382
</P><PRE
 
1383
CLASS="PROGRAMLISTING"
 
1384
>EXEC SQL include sqlda.h;
 
1385
 
 
1386
sqlda_t *sqlda1; /* an output descriptor */
 
1387
sqlda_t *sqlda2; /* an input descriptor  */</PRE
 
1388
><P>
 
1389
    </P
 
1390
><P
 
1391
>     Next, connect to the database, prepare a statement, and declare a
 
1392
     cursor for the prepared statement.
 
1393
</P><PRE
 
1394
CLASS="PROGRAMLISTING"
 
1395
>int
 
1396
main(void)
 
1397
{
 
1398
    EXEC SQL BEGIN DECLARE SECTION;
 
1399
    char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
 
1400
    EXEC SQL END DECLARE SECTION;
 
1401
 
 
1402
    EXEC SQL CONNECT TO testdb AS con1 USER testuser;
 
1403
 
 
1404
    EXEC SQL PREPARE stmt1 FROM :query;
 
1405
    EXEC SQL DECLARE cur1 CURSOR FOR stmt1;</PRE
 
1406
><P>
 
1407
    </P
 
1408
><P
 
1409
>     Next, put some values in the input SQLDA for the input
 
1410
     parameters.  Allocate memory for the input SQLDA, and set the
 
1411
     number of input parameters to <TT
 
1412
CLASS="LITERAL"
 
1413
>sqln</TT
 
1414
>.  Store
 
1415
     type, value, and value length into <TT
 
1416
CLASS="LITERAL"
 
1417
>sqltype</TT
 
1418
>,
 
1419
     <TT
 
1420
CLASS="LITERAL"
 
1421
>sqldata</TT
 
1422
>, and <TT
 
1423
CLASS="LITERAL"
 
1424
>sqllen</TT
 
1425
> in the
 
1426
     <TT
 
1427
CLASS="LITERAL"
 
1428
>sqlvar</TT
 
1429
> structure.
 
1430
 
 
1431
</P><PRE
 
1432
CLASS="PROGRAMLISTING"
 
1433
>    /* Create SQLDA structure for input parameters. */
 
1434
    sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1435
    memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1436
    sqlda2-&#62;sqln = 2; /* number of input variables */
 
1437
 
 
1438
    sqlda2-&#62;sqlvar[0].sqltype = ECPGt_char;
 
1439
    sqlda2-&#62;sqlvar[0].sqldata = "postgres";
 
1440
    sqlda2-&#62;sqlvar[0].sqllen  = 8;
 
1441
 
 
1442
    intval = 1;
 
1443
    sqlda2-&#62;sqlvar[1].sqltype = ECPGt_int;
 
1444
    sqlda2-&#62;sqlvar[1].sqldata = (char *)&amp;intval;
 
1445
    sqlda2-&#62;sqlvar[1].sqllen  = sizeof(intval);</PRE
 
1446
><P>
 
1447
    </P
 
1448
><P
 
1449
>     After setting up the input SQLDA, open a cursor with the input
 
1450
     SQLDA.
 
1451
 
 
1452
</P><PRE
 
1453
CLASS="PROGRAMLISTING"
 
1454
>    /* Open a cursor with input parameters. */
 
1455
    EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;</PRE
 
1456
><P>
 
1457
    </P
 
1458
><P
 
1459
>     Fetch rows into the output SQLDA from the opened cursor.
 
1460
     (Generally, you have to call <TT
 
1461
CLASS="COMMAND"
 
1462
>FETCH</TT
 
1463
> repeatedly
 
1464
     in the loop, to fetch all rows in the result set.)
 
1465
</P><PRE
 
1466
CLASS="PROGRAMLISTING"
 
1467
>    while (1)
 
1468
    {
 
1469
        sqlda_t *cur_sqlda;
 
1470
 
 
1471
        /* Assign descriptor to the cursor  */
 
1472
        EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;</PRE
 
1473
><P>
 
1474
    </P
 
1475
><P
 
1476
>     Next, retrieve the fetched records from the SQLDA, by following
 
1477
     the linked list of the <TT
 
1478
CLASS="TYPE"
 
1479
>sqlda_t</TT
 
1480
> structure.
 
1481
</P><PRE
 
1482
CLASS="PROGRAMLISTING"
 
1483
>    for (cur_sqlda = sqlda1 ;
 
1484
         cur_sqlda != NULL ;
 
1485
         cur_sqlda = cur_sqlda-&#62;desc_next)
 
1486
    {
 
1487
        ...</PRE
 
1488
><P>
 
1489
    </P
 
1490
><P
 
1491
>     Read each columns in the first record.  The number of columns is
 
1492
     stored in <TT
 
1493
CLASS="STRUCTFIELD"
 
1494
>sqld</TT
 
1495
>, the actual data of the first
 
1496
     column is stored in <TT
 
1497
CLASS="LITERAL"
 
1498
>sqlvar[0]</TT
 
1499
>, both members of
 
1500
     the <TT
 
1501
CLASS="TYPE"
 
1502
>sqlda_t</TT
 
1503
> structure.
 
1504
 
 
1505
</P><PRE
 
1506
CLASS="PROGRAMLISTING"
 
1507
>        /* Print every column in a row. */
 
1508
        for (i = 0; i &lt; sqlda1-&gt;sqld; i++)
 
1509
        {
 
1510
            sqlvar_t v = sqlda1-&#62;sqlvar[i];
 
1511
            char *sqldata = v.sqldata;
 
1512
            short sqllen  = v.sqllen;
 
1513
 
 
1514
            strncpy(name_buf, v.sqlname.data, v.sqlname.length);
 
1515
            name_buf[v.sqlname.length] = '\0';</PRE
 
1516
><P>
 
1517
    </P
 
1518
><P
 
1519
>     Now, the column data is stored in the variable <TT
 
1520
CLASS="VARNAME"
 
1521
>v</TT
 
1522
>.
 
1523
     Copy every datum into host variables, looking
 
1524
     at <TT
 
1525
CLASS="LITERAL"
 
1526
>v.sqltype</TT
 
1527
> for the type of the column.
 
1528
</P><PRE
 
1529
CLASS="PROGRAMLISTING"
 
1530
>            switch (v.sqltype) {
 
1531
                int intval;
 
1532
                double doubleval;
 
1533
                unsigned long long int longlongval;
 
1534
 
 
1535
                case ECPGt_char:
 
1536
                    memset(&amp;var_buf, 0, sizeof(var_buf));
 
1537
                    memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &#60;= sqllen ? sizeof(var_buf)-1 : sqllen));
 
1538
                    break;
 
1539
 
 
1540
                case ECPGt_int: /* integer */
 
1541
                    memcpy(&amp;intval, sqldata, sqllen);
 
1542
                    snprintf(var_buf, sizeof(var_buf), "%d", intval);
 
1543
                    break;
 
1544
 
 
1545
                ...
 
1546
 
 
1547
                default:
 
1548
                    ...
 
1549
            }
 
1550
 
 
1551
            printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
 
1552
        }</PRE
 
1553
><P>
 
1554
    </P
 
1555
><P
 
1556
>     Close the cursor after processing all of records, and disconnect
 
1557
     from the database.
 
1558
</P><PRE
 
1559
CLASS="PROGRAMLISTING"
 
1560
>    EXEC SQL CLOSE cur1;
 
1561
    EXEC SQL COMMIT;
 
1562
 
 
1563
    EXEC SQL DISCONNECT ALL;</PRE
 
1564
><P>
 
1565
    </P
 
1566
><P
 
1567
>     The whole program is shown
 
1568
     in <A
 
1569
HREF="ecpg-descriptors.html#ECPG-SQLDA-EXAMPLE-EXAMPLE"
 
1570
>Example 33-1</A
 
1571
>.
 
1572
    </P
 
1573
><DIV
 
1574
CLASS="EXAMPLE"
 
1575
><A
 
1576
NAME="ECPG-SQLDA-EXAMPLE-EXAMPLE"
 
1577
></A
 
1578
><P
 
1579
><B
 
1580
>Example 33-1. Example SQLDA Program</B
 
1581
></P
 
1582
><PRE
 
1583
CLASS="PROGRAMLISTING"
 
1584
>#include &lt;stdlib.h&#62;
 
1585
#include &lt;string.h&#62;
 
1586
#include &lt;stdlib.h&#62;
 
1587
#include &lt;stdio.h&#62;
 
1588
#include &lt;unistd.h&#62;
 
1589
 
 
1590
EXEC SQL include sqlda.h;
 
1591
 
 
1592
sqlda_t *sqlda1; /* descriptor for output */
 
1593
sqlda_t *sqlda2; /* descriptor for input */
 
1594
 
 
1595
EXEC SQL WHENEVER NOT FOUND DO BREAK;
 
1596
EXEC SQL WHENEVER SQLERROR STOP;
 
1597
 
 
1598
int
 
1599
main(void)
 
1600
{
 
1601
    EXEC SQL BEGIN DECLARE SECTION;
 
1602
    char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
 
1603
 
 
1604
    int intval;
 
1605
    unsigned long long int longlongval;
 
1606
    EXEC SQL END DECLARE SECTION;
 
1607
 
 
1608
    EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
 
1609
 
 
1610
    EXEC SQL PREPARE stmt1 FROM :query;
 
1611
    EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
 
1612
 
 
1613
    /* Create a SQLDA structure for an input parameter */
 
1614
    sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1615
    memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
 
1616
    sqlda2-&#62;sqln = 2; /* a number of input variables */
 
1617
 
 
1618
    sqlda2-&#62;sqlvar[0].sqltype = ECPGt_char;
 
1619
    sqlda2-&#62;sqlvar[0].sqldata = "postgres";
 
1620
    sqlda2-&#62;sqlvar[0].sqllen  = 8;
 
1621
 
 
1622
    intval = 1;
 
1623
    sqlda2-&#62;sqlvar[1].sqltype = ECPGt_int;
 
1624
    sqlda2-&#62;sqlvar[1].sqldata = (char *) &amp;intval;
 
1625
    sqlda2-&#62;sqlvar[1].sqllen  = sizeof(intval);
 
1626
 
 
1627
    /* Open a cursor with input parameters. */
 
1628
    EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
 
1629
 
 
1630
    while (1)
 
1631
    {
 
1632
        sqlda_t *cur_sqlda;
 
1633
 
 
1634
        /* Assign descriptor to the cursor  */
 
1635
        EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
 
1636
 
 
1637
        for (cur_sqlda = sqlda1 ;
 
1638
             cur_sqlda != NULL ;
 
1639
             cur_sqlda = cur_sqlda-&#62;desc_next)
 
1640
        {
 
1641
            int i;
 
1642
            char name_buf[1024];
 
1643
            char var_buf[1024];
 
1644
 
 
1645
            /* Print every column in a row. */
 
1646
            for (i=0 ; i&lt;cur_sqlda-&#62;sqld ; i++)
 
1647
            {
 
1648
                sqlvar_t v = cur_sqlda-&#62;sqlvar[i];
 
1649
                char *sqldata = v.sqldata;
 
1650
                short sqllen  = v.sqllen;
 
1651
 
 
1652
                strncpy(name_buf, v.sqlname.data, v.sqlname.length);
 
1653
                name_buf[v.sqlname.length] = '\0';
 
1654
 
 
1655
                switch (v.sqltype)
 
1656
                {
 
1657
                    case ECPGt_char:
 
1658
                        memset(&amp;var_buf, 0, sizeof(var_buf));
 
1659
                        memcpy(&amp;var_buf, sqldata, (sizeof(var_buf)&lt;=sqllen ? sizeof(var_buf)-1 : sqllen) );
 
1660
                        break;
 
1661
 
 
1662
                    case ECPGt_int: /* integer */
 
1663
                        memcpy(&amp;intval, sqldata, sqllen);
 
1664
                        snprintf(var_buf, sizeof(var_buf), "%d", intval);
 
1665
                        break;
 
1666
 
 
1667
                    case ECPGt_long_long: /* bigint */
 
1668
                        memcpy(&amp;longlongval, sqldata, sqllen);
 
1669
                        snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
 
1670
                        break;
 
1671
 
 
1672
                    default:
 
1673
                    {
 
1674
                        int i;
 
1675
                        memset(var_buf, 0, sizeof(var_buf));
 
1676
                        for (i = 0; i &lt; sqllen; i++)
 
1677
                        {
 
1678
                            char tmpbuf[16];
 
1679
                            snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]);
 
1680
                            strncat(var_buf, tmpbuf, sizeof(var_buf));
 
1681
                        }
 
1682
                    }
 
1683
                        break;
 
1684
                }
 
1685
 
 
1686
                printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
 
1687
            }
 
1688
 
 
1689
            printf("\n");
 
1690
        }
 
1691
    }
 
1692
 
 
1693
    EXEC SQL CLOSE cur1;
 
1694
    EXEC SQL COMMIT;
 
1695
 
 
1696
    EXEC SQL DISCONNECT ALL;
 
1697
 
 
1698
    return 0;
 
1699
}</PRE
 
1700
><P
 
1701
>      The output of this example should look something like the
 
1702
      following (some numbers will vary).
 
1703
     </P
 
1704
><PRE
 
1705
CLASS="SCREEN"
 
1706
>oid = 1 (type: 1)
 
1707
datname = template1 (type: 1)
 
1708
datdba = 10 (type: 1)
 
1709
encoding = 0 (type: 5)
 
1710
datistemplate = t (type: 1)
 
1711
datallowconn = t (type: 1)
 
1712
datconnlimit = -1 (type: 5)
 
1713
datlastsysoid = 11510 (type: 1)
 
1714
datfrozenxid = 379 (type: 1)
 
1715
dattablespace = 1663 (type: 1)
 
1716
datconfig =  (type: 1)
 
1717
datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
 
1718
datid = 1 (type: 1)
 
1719
datname = template1 (type: 1)
 
1720
numbackends = 0 (type: 5)
 
1721
xact_commit = 113606 (type: 9)
 
1722
xact_rollback = 0 (type: 9)
 
1723
blks_read = 130 (type: 9)
 
1724
blks_hit = 7341714 (type: 9)
 
1725
tup_returned = 38262679 (type: 9)
 
1726
tup_fetched = 1836281 (type: 9)
 
1727
tup_inserted = 0 (type: 9)
 
1728
tup_updated = 0 (type: 9)
 
1729
tup_deleted = 0 (type: 9)
 
1730
 
 
1731
oid = 11511 (type: 1)
 
1732
datname = postgres (type: 1)
 
1733
datdba = 10 (type: 1)
 
1734
encoding = 0 (type: 5)
 
1735
datistemplate = f (type: 1)
 
1736
datallowconn = t (type: 1)
 
1737
datconnlimit = -1 (type: 5)
 
1738
datlastsysoid = 11510 (type: 1)
 
1739
datfrozenxid = 379 (type: 1)
 
1740
dattablespace = 1663 (type: 1)
 
1741
datconfig =  (type: 1)
 
1742
datacl =  (type: 1)
 
1743
datid = 11511 (type: 1)
 
1744
datname = postgres (type: 1)
 
1745
numbackends = 0 (type: 5)
 
1746
xact_commit = 221069 (type: 9)
 
1747
xact_rollback = 18 (type: 9)
 
1748
blks_read = 1176 (type: 9)
 
1749
blks_hit = 13943750 (type: 9)
 
1750
tup_returned = 77410091 (type: 9)
 
1751
tup_fetched = 3253694 (type: 9)
 
1752
tup_inserted = 0 (type: 9)
 
1753
tup_updated = 0 (type: 9)
 
1754
tup_deleted = 0 (type: 9)</PRE
 
1755
></DIV
 
1756
></DIV
 
1757
></DIV
 
1758
></DIV
 
1759
><DIV
 
1760
CLASS="NAVFOOTER"
 
1761
><HR
 
1762
ALIGN="LEFT"
 
1763
WIDTH="100%"><TABLE
 
1764
SUMMARY="Footer navigation table"
 
1765
WIDTH="100%"
 
1766
BORDER="0"
 
1767
CELLPADDING="0"
 
1768
CELLSPACING="0"
 
1769
><TR
 
1770
><TD
 
1771
WIDTH="33%"
 
1772
ALIGN="left"
 
1773
VALIGN="top"
 
1774
><A
 
1775
HREF="ecpg-pgtypes.html"
 
1776
ACCESSKEY="P"
 
1777
>Prev</A
 
1778
></TD
 
1779
><TD
 
1780
WIDTH="34%"
 
1781
ALIGN="center"
 
1782
VALIGN="top"
 
1783
><A
 
1784
HREF="index.html"
 
1785
ACCESSKEY="H"
 
1786
>Home</A
 
1787
></TD
 
1788
><TD
 
1789
WIDTH="33%"
 
1790
ALIGN="right"
 
1791
VALIGN="top"
 
1792
><A
 
1793
HREF="ecpg-errors.html"
 
1794
ACCESSKEY="N"
 
1795
>Next</A
 
1796
></TD
 
1797
></TR
 
1798
><TR
 
1799
><TD
 
1800
WIDTH="33%"
 
1801
ALIGN="left"
 
1802
VALIGN="top"
 
1803
>pgtypes Library</TD
 
1804
><TD
 
1805
WIDTH="34%"
 
1806
ALIGN="center"
 
1807
VALIGN="top"
 
1808
><A
 
1809
HREF="ecpg.html"
 
1810
ACCESSKEY="U"
 
1811
>Up</A
 
1812
></TD
 
1813
><TD
 
1814
WIDTH="33%"
 
1815
ALIGN="right"
 
1816
VALIGN="top"
 
1817
>Error Handling</TD
 
1818
></TR
 
1819
></TABLE
 
1820
></DIV
 
1821
></BODY
 
1822
></HTML
 
1823
>
 
 
b'\\ No newline at end of file'