8. SQL Statements : COPY FROM | INTO PROGRAM : Handler Code Examples : COPY FROM PROGRAM Using Fixed-length Formats
 
COPY FROM PROGRAM Using Fixed-length Formats
/*
** Copy from program using fixed length formats.
** Table contains:
**      integer
**      char(20)
**      float
**      date
**
** Copy uses formats:
**      integer
**      char(20)
**      float8
**      char(25)
**
** The user-defined handler copies data from a structure into the tuple
** buffer. Because formats are not nullable, the handler does not have
** to place a "null terminator" byte or other null indicator into the
** buffer.
*/
 
#include <stdio.h>
#include <time.h>
 
EXEC SQL INCLUDE SQLCA;
 
/* Declare some "canned" data */
struct {
    int         col1;
    char        col2[21];
    double      col3;
    char        col4[25];
} get_data[] = {
{ 1, "this is the 1st row ", 1.1, "21-mar-1991              "},
{ 2, "this is the 2nd row ", 2.2, "today                    "},
{ 3, "this is row three ", 3.3, "19-apr-91                "},
{ 4, "                    ", 0.0, "                          "},
{ 0, "", 0.0, ""}
};
 
static int row_num = 0;
void     Print_Error();
 
main()
{
 
int get_row();
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL END DECLARE SECTION;
 
EXEC SQL CONNECT dbname;
if (sqlca.sqlcode != 0)
{
Print_Error();
exit(1);
}
 
EXEC SQL DROP TABLE t;
EXEC SQL WHENEVER SQLERROR call Print_Error;
EXEC SQL CREATE TABLE t (col1 INTEGER not null,
                         col2 CHAR(20) not null,
                         col3 FLOAT not null,
                         col4 DATE not null);
 
EXEC SQL COPY TABLE t (col1=INTEGER,
                       col2=CHAR(20),
                       col3=FLOAT8,
                       col4=CHAR(25))
        FROM PROGRAM WITH COPYHANDLER = get_row;
 
EXEC SQL DISCONNECT;
printf("\nTerminated successfully\n");
exit(0);
}
 
int
get_row(byte_length, row, bytes_used)
int     *byte_length;
char    *row;
int     *bytes_used;
{
    int i;
    char *top = row;
    char *fromp;
 
    if (get_data[row_num].col2[0] == 0)    {
        *bytes_used = 0;            /* Indicate all rows copied */
        return 0;
    }
 
    /* Copy integer data a byte at a time */
    fromp = (char *)&get_data[row_num].col1;
    for (i = 0; i < sizeof(int); i++)
    {
        *top++ = *fromp++;
    }
    fromp = get_data[row_num].col2;
 
    /* Copy 20 bytes of char data */
    for (i = 0; i < 20; i++)
    {
        *top++ = *fromp++;
    }
    fromp = (char *)&get_data[row_num].col3;
 
    /* Copy float data a byte at a time */
    for (i = 0; i < sizeof(double); i++)
    {
        *top++ = *fromp++;
    }
    fromp = get_data[row_num].col4;
 
    /* Copy 25 bytes of char data */
    for (i = 0; i < 25; i++)
    {
        *top++ = *fromp++;
    }
 
    *bytes_used = top - row;
    row_num++;
 
    return 0;
}
 
 
void Print_Error()
{
EXEC SQL BEGIN DECLARE SECTION;
Char    error_buf[2000];
EXEC SQL END DECLARE SECTION;
 
EXEC SQL INQUIRE_INGRES (:error_buf = ERRORTEXT);
printf("\nSQL Error:\n\n%s \n", error_buf);
printf("\nTerminated with Errors \n");
 
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("SQL: Exiting Copy from program using fixed length formats\n");
EXEC SQL ROLLBACK;
EXEC SQL DISCONNECT;
 
exit(-1);
}