LightDB pro*c支持exec sql for :i update(or insert)语法

背景

oracle

在适配过程中,发现pro*c支持exec sql for :i update(or insert)语法,其功能是取代

for(;;)
{
	update(or insert)语法;
}

其中i决定循环执行的次数,update(or insert)表示循环执行的次数。
我们在oracle环境下测试得到如下经验:
(1) char str[]一维数组在update更新时,在where条件中不能使用如下格式作为右值":str[1]"。如果出现这种情况,则报段错误。
test
测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL INCLUDE sqlca;
EXEC SQL BEGIN DECLARE SECTION;
char *uid = "test/test@ip/test";
EXEC SQL END DECLARE SECTION;

int
main(void)
{
    int i=2;
    EXEC SQL WHENEVER SQLERROR continue;
    char arr[26]="123456789";
    EXEC SQL CONNECT :uid;
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    EXEC SQL FOR :i update test set a = :arr where a = :arr[0] ;
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    EXEC SQL commit;
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    exit(0);
}

(2)其他类型如上使用时(int,long等),能正常更新

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL INCLUDE sqlca;
EXEC SQL BEGIN DECLARE SECTION;
char *uid = "test/test@ip/test";
EXEC SQL END DECLARE SECTION;

int
main(void)
{
    int i=2;
    EXEC SQL WHENEVER SQLERROR continue;
    int arr[26]={1,2,3,4,5,6,7,8,9,10,11,12,13,14};
    EXEC SQL CONNECT :uid;
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    EXEC SQL FOR :i update test set a = :arr where a = :arr[1];
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    EXEC SQL commit;
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    exit(0);
}

(3)oracle支持的主变量类型如下:

test2
其中int、short、long、long long、float、double类型作为主变量只能声明成一维数组;
test

varchar类型作为主变量不能超过二维数组。
test4

LightDB

LightDB在此基础之上进行兼容。在功能上,兼容上述oracle所描述的几点。并且由于LightDB支持的类型更多,因此需要多加一下几点说明:
(1)decimal、string、timestamp、date、interval、bool、numeric类型作为主变量只能声明成一维数组;
(2)varchar、bytea类型作为主变量使用只能声明成数组;并且声明成三维数组也会当成二维数组进行处理。

测试

正常测试

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

EXEC SQL INCLUDE ../regression;
exec sql include ../../preproc/type.h;
#include <pgtypes_date.h>
#include <pgtypes_interval.h>
#include <pgtypes_numeric.h>
#include <pgtypes_timestamp.h>

exec sql type string is char[11];
typedef char string[11];

exec sql begin declare section;
/* 声明结构体 */
struct mixed_statements
{
    /* 数值类型数值 */
	int v_error_no[10];
    numeric n[10];
    short st[10];
    long lg[10];
    long long  llg[10];
    float ft[10];
    double db[10];
    decimal dl[10];

    /* 字符串类型 */
    char val[10][10];
    varchar vc[10][10];
    bytea  ba[10][10];
    char  c[10];
    string str_value[10];

    /* 时间类型 */
    timestamp ts[10];
    date d[10];
    interval inter[10];

    /* 布尔类型 */
    bool bl[10];
};

/* 字符串三维数组 */
struct string_declaration
{
    /* 字符串类型 */
    char val[10][10][10];
};

union u_mixed_statements
{
    /* 数值类型数值 */
	int v_error_no[10];
    numeric n[10];
    short st[10];
    long lg[10];
    long long  llg[10];
    float ft[10];
    double db[10];
    decimal dl[10];

    /* 字符串类型 */
    char val[10][10];
    varchar vc[10][10];
    bytea  ba[10][10];
    char  c[10];
    string str_value[10];

    /* 时间类型 */
    timestamp ts[10];
    date d[10];
    interval inter[10];

    /* 布尔类型 */
    bool bl[10];
};

/* 字符串三维数组 */
union u_string_declaration
{
    /* 字符串类型 */
    char val[10][10][10];
};

/* 结构体嵌套 */
struct nested_structure
{
    struct mixed_statements *nsms;
    struct string_declaration *nssd;
};

/* union嵌套 */
union nested_union
{
    union u_mixed_statements u_nsms;
    union u_string_declaration u_unssd;
};

exec sql end declare section;

static void
print_sqlca()
{
    fprintf(stderr, "==== sqlca ====\n");
    fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
    fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
    fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
    fprintf(stderr, "===============\n");
}

int main() 
{
    /* 声明主变量 */
	exec sql begin declare section;
	int v_error_no = 1;
	char val[20] = "dsd";
	numeric n;
	timestamp ts;
	date d;
	short st =1;
	long lg =1;
	long long  llg =1;
	float ft=1;
	double db=1;
	bool bl= false;
	varchar vc[100];
	bytea  ba[100];
	string str_value = "string";
	char  c = 'a';
	decimal dl;
	interval inter;
    struct mixed_statements *oda = NULL;
    struct string_declaration *tda = NULL;
    struct nested_structure *sns = NULL;
    union u_mixed_statements uoda;
    union u_string_declaration utda;
    union nested_union snu;
    int i, j = 0;
	exec sql end declare section;

	char str[10];
	numeric *value;
    oda = (struct mixed_statements* )malloc(sizeof(struct mixed_statements));
    tda = (struct string_declaration* )malloc(sizeof(struct string_declaration));

    /* 结构体嵌套赋初值 */
    sns = (struct nested_structure* )malloc(sizeof(struct nested_structure));
    sns->nsms = (struct mixed_statements* )malloc(sizeof(struct mixed_statements));
    sns->nssd =  (struct string_declaration* )malloc(sizeof(struct string_declaration));

    /* ----------------------------普通变量赋值---------------------------- */
    /* timestampe类型赋初值 */
	sprintf(str, "2000-1-1 0%d:00:00\n", 1);
	ts = PGTYPEStimestamp_from_asc(str, NULL);
    /* date类型赋初值 */
	sprintf(str, "2000-1-1%d\n", 1);
	d = PGTYPESdate_from_asc(str, NULL);
    /* interval类型赋初值 */
	sprintf(str, "%d hours\n", 11);
	inter = *PGTYPESinterval_from_asc(str, NULL);
    /* numeric类型赋初值 */
	value = PGTYPESnumeric_new();
	PGTYPESnumeric_from_int(1, value);
    /* decimal类型赋初值 */
	n = *value;
	PGTYPESnumeric_to_decimal(value, &dl);

    /* varchar数组赋初值 */
	memcpy(vc.arr, "abc", 10);
	vc.len = 10;

    /* bytea数组赋初值 */
	memcpy(ba.arr, "aaaa", 10);
	ba.len = 10;

    memcpy(oda->c, "11111111\n", 10);
    memcpy(sns->nsms->c, "11111111\n", 10);

    /* ----------------------------结构体混合数组赋值---------------------------- */
    for(i = 0; i < 10; i++)
    {
        oda->v_error_no[i] = i;
        sns->nsms->v_error_no[i] = i;
        oda->st[i] = i;
        sns->nsms->st[i] = i;
        oda->lg[i] = i;
        sns->nsms->lg[i] = i;
        oda->llg[i] = i;
        sns->nsms->llg[i] = i;
        oda->ft[i] = i;
        sns->nsms->ft[i] = i;
        oda->db[i] = i;
        sns->nsms->db[i] = i;
        oda->bl[i] = false;
        sns->nsms->bl[i] = false;

        sprintf(str, "dsd%d\n", i);
        memcpy(oda->val[i], str, 10);
        memcpy(sns->nsms->val[i], str, 10);

        sprintf(str, "string%d\n", i);
        memcpy(oda->str_value[i], str, 10);
        memcpy(sns->nsms->str_value[i], str, 10);

        /* timestampe类型赋初值 */
        sprintf(str, "2000-1-1 0%d:00:00\n", i);
        oda->ts[i] = PGTYPEStimestamp_from_asc(str, NULL);
        sns->nsms->ts[i] = PGTYPEStimestamp_from_asc(str, NULL);
        /* date类型赋初值 */
        sprintf(str, "2000-1-1%d\n", i);
        oda->d[i] = PGTYPESdate_from_asc(str, NULL);
        sns->nsms->d[i] = PGTYPESdate_from_asc(str, NULL);
        /* interval类型赋初值 */
        sprintf(str, "%d hours\n", i);
        oda->inter[i] = *PGTYPESinterval_from_asc(str, NULL);
        sns->nsms->inter[i] = *PGTYPESinterval_from_asc(str, NULL);

        value = PGTYPESnumeric_new();
        PGTYPESnumeric_from_int(i, value);

        /* numeric类型赋初值 */
        oda->n[i] = *value;
        sns->nsms->n[i] = *value;

        /* decimal类型赋初值 */
        PGTYPESnumeric_to_decimal(value, &(oda->dl[i]));
        PGTYPESnumeric_to_decimal(value, &(sns->nsms->dl[i]));

        /* varchar数组赋初值 */
        sprintf(str, "abc%d\n", i);
        memcpy(oda->vc[i].arr, str, 10);
        oda->vc[i].len = 10;
        memcpy(sns->nsms->vc[i].arr, str, 10);
        sns->nsms->vc[i].len = 10;

        /* bytea数组赋初值 */
        sprintf(str, "aaaa%d\n", i);
        memcpy(oda->ba[i].arr, str, 10);
        oda->ba[i].len = 10;
        memcpy(sns->nsms->ba[i].arr, str, 10);
        sns->nsms->ba[i].len = 10;
    }

    /* ----------------------------结构体三维数组赋值---------------------------- */
    for(i = 0; i < 10; i++)
        for(j = 0; j < 10; j++)
        {
            sprintf(str, "dsd%d\n", i);
            memcpy(tda->val[i][j], str, 10);
            memcpy(sns->nssd->val[i][j], str, 10);
        }

    /* 打开一个调试日志 */
	ECPGdebug(1, stderr);

	/* 连接数据库 */
	EXEC SQL CONNECT TO oracledb;

	/* 设置 waring 和 error 的处理方式 */
	EXEC SQL WHENEVER SQLWARNING SQLPRINT;
	EXEC SQL WHENEVER SQLERROR CALL print_sqlca();

	/* -----------------------混合数组插入数据----------------------- */
    {
        /* 建表 */
        exec sql create table test_for_count(
            k1 integer,
            k2 char(10),
            k3 numeric,
            k4 timestamp,
            k5 date,
            k6 smallint,
            k7 bigint,
            k8 bigint,
            k9 real,
            k10 double precision,
            k11 bool,
            k12 varchar(100),
            k13 bytea,
            k14 text,
            k15 char,
            k16 decimal,
            k17 interval);

        i = 5;
        EXEC SQL for :i insert into test_for_count values
        (:oda->v_error_no, :oda->val, :oda->n, :oda->ts, :oda->d,
        :oda->st, :oda->lg, :oda->llg, :oda->ft, :oda->db, :oda->bl, :oda->vc,
        :oda->ba, :oda->str_value, :oda->c, :oda->dl, :oda->inter);

        i = 5;
        EXEC SQL for :i update test_for_count set k1 = :oda->v_error_no, k2 = :oda->val, k3 = :oda->n,
        k4 = :oda->ts, k5 = :oda->d, k6 = :oda->st, k7 = :oda->lg, k8 = :oda->llg, k9 = :oda->ft, k10 = :oda->db,
        k11 = :oda->bl, k12 = :oda->vc, k13 = :oda->ba, k14 = :oda->str_value, k15 = :oda->c,
        k16 = :oda->dl, k17 = :oda->inter;
        /* 声明游标 */
        EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select * from test_for_count;

        /* 打开游标 */
        EXEC SQL OPEN cur_for_count_insert;

        /* 在达到结果集末尾时,跳出 while 循环 */
        EXEC SQL WHENEVER NOT FOUND DO BREAK;

        printf("-----------------------Mixed Array Output-----------------------\n");

        /* 游标获取打印 */
        while(1)
        {
            EXEC SQL FETCH cur_for_count_insert INTO :v_error_no, :val, :n, :ts, :d, :st, :lg, :llg, :ft, :db, :bl, :vc, :ba, :str_value, :c, :dl, :inter;
            PGTYPESnumeric_from_decimal(&dl, value);
            printf("-----------------------Get result set-----------------------\n");
            printf("k1 = %d\nk2 = %s\nk3 = %s\nk4 = %s\nk5 = %s\nk6 = %d\nk7 = %ld\nk8 = %lld\nk9 = %f\nk10 = %f\nk11 = %d\nk12 = %s\nk13 = %s\nk14 = %s\nk15 = %d\nk16 = %s\nk17 = %s\n",
                v_error_no, val, PGTYPESnumeric_to_asc(&n, -1), PGTYPEStimestamp_to_asc(ts), PGTYPESdate_to_asc(d), st, lg, llg, ft, db, bl, vc.arr, ba.arr, str_value, c, PGTYPESnumeric_to_asc(value, -1), PGTYPESinterval_to_asc(&inter));
        }

        /* 关闭游标 */
        EXEC SQL CLOSE cur_for_count_insert;
        EXEC SQL DROP TABLE test_for_count;
    }

	/* -----------------------三维数组插入数据----------------------- */
    {
        /* 建表 */
        exec sql create table test_for_count(
            k1 integer,
            k2 char(10),
            k3 numeric,
            k4 timestamp,
            k5 date,
            k6 smallint,
            k7 bigint,
            k8 bigint,
            k9 real,
            k10 double precision,
            k11 bool,
            k12 varchar(100),
            k13 bytea,
            k14 text,
            k15 char,
            k16 decimal,
            k17 interval);

        i = 5;
        EXEC SQL for :i insert into test_for_count values
        (:oda->v_error_no, :tda->val, :oda->n, :oda->ts, :oda->d,
        :oda->st, :oda->lg, :oda->llg, :oda->ft, :oda->db, :oda->bl, :oda->vc,
        :oda->ba, :oda->str_value, :oda->c, :oda->dl, :oda->inter);

        i = 5;
        EXEC SQL for :i update test_for_count set k1 = :oda->v_error_no, k2 = :oda->val, k3 = :oda->n,
        k4 = :oda->ts, k5 = :oda->d, k6 = :oda->st, k7 = :oda->lg, k8 = :oda->llg, k9 = :oda->ft, k10 = :oda->db,
        k11 = :oda->bl, k12 = :oda->vc, k13 = :oda->ba, k14 = :oda->str_value, k15 = :oda->c,
        k16 = :oda->dl, k17 = :oda->inter;

        /* 声明游标 */
        EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select * from test_for_count;

        /* 打开游标 */
        EXEC SQL OPEN cur_for_count_insert;

        printf("-----------------------3-Dimensional Array Output-----------------------\n");

        /* 游标获取打印 */
        while(1)
        {
            EXEC SQL FETCH cur_for_count_insert INTO :v_error_no, :val, :n, :ts, :d, :st, :lg, :llg, :ft, :db, :bl, :vc, :ba, :str_value, :c, :dl, :inter;
            PGTYPESnumeric_from_decimal(&dl, value);
            printf("-----------------------Get result set-----------------------\n");
            printf("k1 = %d\nk2 = %s\nk3 = %s\nk4 = %s\nk5 = %s\nk6 = %d\nk7 = %ld\nk8 = %lld\nk9 = %f\nk10 = %f\nk11 = %d\nk12 = %s\nk13 = %s\nk14 = %s\nk15 = %d\nk16 = %s\nk17 = %s\n",
                v_error_no, val, PGTYPESnumeric_to_asc(&n, -1), PGTYPEStimestamp_to_asc(ts), PGTYPESdate_to_asc(d), st, lg, llg, ft, db, bl, vc.arr, ba.arr, str_value, c, PGTYPESnumeric_to_asc(value, -1), PGTYPESinterval_to_asc(&inter));
        }

        /* 关闭游标 */
        EXEC SQL CLOSE cur_for_count_insert;
        EXEC SQL DROP TABLE test_for_count;
    }

	/* -----------------------结构体嵌套插入数据----------------------- */
    {
        /* 建表 */
        exec sql create table test_for_count(
            k1 integer,
            k2 char(10),
            k3 numeric,
            k4 timestamp,
            k5 date,
            k6 smallint,
            k7 bigint,
            k8 bigint,
            k9 real,
            k10 double precision,
            k11 bool,
            k12 varchar(100),
            k13 bytea,
            k14 text,
            k15 char,
            k16 decimal,
            k17 interval);

        i = 5;
        EXEC SQL for :i insert into test_for_count values
        (:sns->nsms->v_error_no, :sns->nssd->val, :sns->nsms->n, :sns->nsms->ts, :sns->nsms->d,
        :sns->nsms->st, :sns->nsms->lg, :sns->nsms->llg, :sns->nsms->ft, :sns->nsms->db, :sns->nsms->bl, :sns->nsms->vc,
        :sns->nsms->ba, :sns->nsms->str_value, :sns->nsms->c, :sns->nsms->dl, :sns->nsms->inter);

        i = 5;
        EXEC SQL for :i update test_for_count set k1 = :sns->nsms->v_error_no, k2 = :sns->nsms->val, k3 = :sns->nsms->n,
        k4 = :sns->nsms->ts, k5 = :sns->nsms->d, k6 = :sns->nsms->st, k7 = :sns->nsms->lg, k8 = :sns->nsms->llg, k9 = :sns->nsms->ft, k10 = :sns->nsms->db,
        k11 = :sns->nsms->bl, k12 = :sns->nsms->vc, k13 = :sns->nsms->ba, k14 = :sns->nsms->str_value, k15 = :sns->nsms->c,
        k16 = :sns->nsms->dl, k17 = :sns->nsms->inter;
    
        /* 声明游标 */
        EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select * from test_for_count;

        /* 打开游标 */
        EXEC SQL OPEN cur_for_count_insert;

        printf("-----------------------Structures Nested Output-----------------------\n");

        /* 游标获取打印 */
        while(1)
        {
            EXEC SQL FETCH cur_for_count_insert INTO :v_error_no, :val, :n, :ts, :d, :st, :lg, :llg, :ft, :db, :bl, :vc, :ba, :str_value, :c, :dl, :inter;
            PGTYPESnumeric_from_decimal(&dl, value);
            printf("-----------------------Get result set-----------------------\n");
            printf("k1 = %d\nk2 = %s\nk3 = %s\nk4 = %s\nk5 = %s\nk6 = %d\nk7 = %ld\nk8 = %lld\nk9 = %f\nk10 = %f\nk11 = %d\nk12 = %s\nk13 = %s\nk14 = %s\nk15 = %d\nk16 = %s\nk17 = %s\n",
                v_error_no, val, PGTYPESnumeric_to_asc(&n, -1), PGTYPEStimestamp_to_asc(ts), PGTYPESdate_to_asc(d), st, lg, llg, ft, db, bl, vc.arr, ba.arr, str_value, c, PGTYPESnumeric_to_asc(value, -1), PGTYPESinterval_to_asc(&inter));
        }

        /* 关闭游标 */
        EXEC SQL CLOSE cur_for_count_insert;
        EXEC SQL DROP TABLE test_for_count;
    }
	/* -----------------------union混合数组插入数据----------------------- */
    {
        /* -----------------int类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.v_error_no[i] = i + 1;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k1) values
            (:uoda.v_error_no);

            i = 2;
            EXEC SQL for :i update test_for_count set k1 = :uoda.v_error_no where k1 = 3;
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k1 from test_for_count order by k1 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------union mixed array output-----------------------\n");
            printf("-----------------------test of int type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :v_error_no;
                printf("k1 = %d\n", v_error_no);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
            /*----------------------------------test of int .var[]----------------------------------*/
            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k1) values
            (:uoda.v_error_no);

            i = 2;
            EXEC SQL for :i update test_for_count set k1 = :uoda.v_error_no where k1 = :uoda.v_error_no[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k1 from test_for_count order by k1 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of int .var[]-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :v_error_no;
                printf("k1 = %d\n", v_error_no);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------char类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "dsd%d\n", i);
                memcpy(uoda.val[i], str, 10);
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k2) values
            (:uoda.val);

            i = 2;
            EXEC SQL for :i update test_for_count set k2 = :uoda.val where k2 = :uoda.val[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k2 from test_for_count order by k2 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of char type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :val;
                printf("k2 = %s\n", val);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------numeric类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                value = PGTYPESnumeric_new();
                PGTYPESnumeric_from_int(i, value);

                /* numeric类型赋初值 */
                uoda.n[i] = *value;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k3) values
            (:uoda.n);

            i = 2;
            EXEC SQL for :i update test_for_count set k3 = :uoda.n where k3 = :uoda.n[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k3 from test_for_count order by k3 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of numeric type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :n;
                printf("k3 = %s\n", PGTYPESnumeric_to_asc(&n, -1));
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------timestamp类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "2000-1-1 0%d:00:00\n", i);
                uoda.ts[i] = PGTYPEStimestamp_from_asc(str, NULL);
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k4) values
            (:uoda.ts);

            i = 2;
            EXEC SQL for :i update test_for_count set k4 = :uoda.ts where k4 = :uoda.ts[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k4 from test_for_count order by k4 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of timestamp type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :ts;
                printf("k4 = %s\n", PGTYPEStimestamp_to_asc(ts));
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------date类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "2000-1-1%d\n", i);
                uoda.d[i] = PGTYPESdate_from_asc(str, NULL);
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k5) values
            (:uoda.d);

            i = 2;
            EXEC SQL for :i update test_for_count set k5 = :uoda.d where k5 = :uoda.d[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k5 from test_for_count order by k5 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of date type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :d;
                printf("k5 = %s\n", PGTYPESdate_to_asc(d));
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------short类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.st[i] = i;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k6) values
            (:uoda.st);

            i = 2;
            EXEC SQL for :i update test_for_count set k6 = :uoda.st where k6 = :uoda.st[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k6 from test_for_count order by k6 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of numeric type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :st;
                printf("k6 = %d\n", st);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------long类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.lg[i] = i;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k7) values
            (:uoda.lg);

            i = 2;
            EXEC SQL for :i update test_for_count set k7 = :uoda.lg where k7 = :uoda.lg[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k7 from test_for_count order by k7 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of long type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :lg;
                printf("k7 = %ld\n", lg);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------long long类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.llg[i] = i;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k8) values
            (:uoda.llg);

            i = 2;
            EXEC SQL for :i update test_for_count set k8 = :uoda.llg where k8 = :uoda.llg[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k8 from test_for_count order by k8 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of long long type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :llg;
                printf("k8 = %lld\n", llg);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------float类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.ft[i] = i;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k9) values
            (:uoda.ft);

            i = 2;
            EXEC SQL for :i update test_for_count set k9 = :uoda.ft where k9 = :uoda.ft[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k9 from test_for_count order by k9 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of float type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :ft;
                printf("k9 = %f\n", ft);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------double类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.db[i] = i;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k10) values
            (:uoda.db);

            i = 2;
            EXEC SQL for :i update test_for_count set k10 = :uoda.db where  k10 = :uoda.db[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k10 from test_for_count order by k10 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of double type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :db;
                printf("k10 = %f\n", db);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------varchar类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "abc%d\n", i);
                memcpy(uoda.vc[i].arr, str, 10);
                uoda.vc[i].len = 10;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k12) values
            (:uoda.vc);

            i = 2;
            EXEC SQL for :i update test_for_count set k12 = :uoda.vc where k12 = :uoda.vc[1];
            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k12 from test_for_count order by k12 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of varchar type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :vc;
                printf("k12 = %s\n", vc.arr);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------bytea类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "aaaa%d\n", i);
                memcpy(uoda.ba[i].arr, str, 10);
                uoda.ba[i].len = 10;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k13) values
            (:uoda.ba);

            i = 2;
            EXEC SQL for :i update test_for_count set k13 = :uoda.ba where  k13 = :uoda.ba[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k13 from test_for_count order by k13 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of bytea type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :ba;
                printf("k13 = %s\n", ba.arr);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------string类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "string%d\n", i);
                memcpy(uoda.str_value[i], str, 10);
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k14) values
            (:uoda.str_value);

            i = 2;
            EXEC SQL for :i update test_for_count set k14 = :uoda.str_value where k14 = :uoda.str_value[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k14 from test_for_count order by k14 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of string type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :str_value;
                printf("k14 = %s\n", str_value);
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------decimal类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                value = PGTYPESnumeric_new();
                PGTYPESnumeric_from_int(i, value);

                /* decimal类型赋初值 */
                PGTYPESnumeric_to_decimal(value, &(uoda.dl[i]));
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k16) values
            (:uoda.dl);

            i = 2;
            EXEC SQL for :i update test_for_count set k16 = :uoda.dl where k16 = :uoda.dl[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k16 from test_for_count order by k16 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of decimal type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :dl;
                PGTYPESnumeric_from_decimal(&dl, value);
                printf("k16 = %s\n", PGTYPESnumeric_to_asc(value, -1));
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }

        /* -----------------interval类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                sprintf(str, "%d hours\n", i);
                uoda.inter[i] = *PGTYPESinterval_from_asc(str, NULL);
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k17) values
            (:uoda.inter);

            i = 2;
            EXEC SQL for :i update test_for_count set k17 = :uoda.inter where  k17 = :uoda.inter[1];

            /* 声明游标 */
            EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k17 from test_for_count order by k17 asc;

            /* 打开游标 */
            EXEC SQL OPEN cur_for_count_insert;

            printf("-----------------------test of interval type-----------------------\n");
            /* 游标获取打印 */
            while(1)
            {
                EXEC SQL FETCH cur_for_count_insert INTO :inter;
                printf("k17 = %s\n", PGTYPESinterval_to_asc(&inter));
            }

            /* 关闭游标 */
            EXEC SQL CLOSE cur_for_count_insert;

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }
    }

	/* -----------------------union三维数组插入数据----------------------- */
    /* -----------------char类型测试----------------- */
    {
        for(i = 0; i < 10; i++)
            for(j = 0; j < 10; j++)
            {
                sprintf(str, "dsd%d\n", i);
                memcpy(utda.val[i][j], str, 10);
            }

        /* 建表 */
        exec sql create table test_for_count(
            k1 integer,
            k2 char(10),
            k3 numeric,
            k4 timestamp,
            k5 date,
            k6 smallint,
            k7 bigint,
            k8 bigint,
            k9 real,
            k10 double precision,
            k11 bool,
            k12 varchar(100),
            k13 bytea,
            k14 text,
            k15 char,
            k16 decimal,
            k17 interval);

        i = 3;
        EXEC SQL for :i insert into test_for_count(k2) values
        (:utda.val);

        i = 2;
        EXEC SQL for :i update test_for_count set k2 = :utda.val where k2 =  :utda.val[1];

        /* 声明游标 */
        EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k2 from test_for_count order by k2 asc;

        /* 打开游标 */
        EXEC SQL OPEN cur_for_count_insert;

        printf("-----------------------union 3-Dimensional array output-----------------------\n");
        printf("-----------------------test of char type-----------------------\n");
        /* 游标获取打印 */
        while(1)
        {
            EXEC SQL FETCH cur_for_count_insert INTO :val;
            printf("k2 = %s\n", val);
        }

        /* 关闭游标 */
        EXEC SQL CLOSE cur_for_count_insert;

        /* 清理环境 */
        EXEC SQL DROP table test_for_count;
    }

	/* -----------------------union嵌套插入数据----------------------- */
    /* -----------------char类型测试----------------- */
    {
        for(i = 0; i < 10; i++)
            for(j = 0; j < 10; j++)
            {
                sprintf(str, "dsd%d\n", i);
                memcpy(snu.u_unssd.val[i][j], str, 10);
            }

        /* 建表 */
        exec sql create table test_for_count(
            k1 integer,
            k2 char(10),
            k3 numeric,
            k4 timestamp,
            k5 date,
            k6 smallint,
            k7 bigint,
            k8 bigint,
            k9 real,
            k10 double precision,
            k11 bool,
            k12 varchar(100),
            k13 bytea,
            k14 text,
            k15 char,
            k16 decimal,
            k17 interval);

        i = 3;
        EXEC SQL for :i insert into test_for_count(k2) values
        (:snu.u_unssd.val);

        i = 2;
        EXEC SQL for :i update test_for_count set k2 = :snu.u_unssd.val where k2 = :snu.u_unssd.val[1];

        /* 声明游标 */
        EXEC SQL DECLARE cur_for_count_insert CURSOR FOR select k2 from test_for_count order by k2 asc;

        /* 打开游标 */
        EXEC SQL OPEN cur_for_count_insert;

        printf("-----------------------Union Nested Output-----------------------\n");
        printf("-----------------------test of char type-----------------------\n");
        /* 游标获取打印 */
        while(1)
        {
            EXEC SQL FETCH cur_for_count_insert INTO :val;
            printf("k2 = %s\n", val);
        }

        /* 关闭游标 */
        EXEC SQL CLOSE cur_for_count_insert;

        /* 清理环境 */
        EXEC SQL DROP table test_for_count;
    }

    if (value)
        PGTYPESnumeric_free(value);

    if (oda)
        free(oda);

   if (tda)
        free(tda);

    if (sns->nsms)
        free(sns->nsms);

    if (sns->nssd)
        free(sns->nssd);

    if (sns)
        free(sns);

    /* 断开连接 */
	exec sql disconnect;

	return 0;
}

异常测试1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

EXEC SQL INCLUDE ../regression;
exec sql include ../../preproc/type.h;
#include <pgtypes_date.h>
#include <pgtypes_interval.h>
#include <pgtypes_numeric.h>
#include <pgtypes_timestamp.h>

exec sql type string is char[11];
typedef char string[11];

exec sql begin declare section;

union u_mixed_statements
{
    /* 数值类型数值 */
	int v_error_no[10];
    numeric n[10];
    short st[10];
    long lg[10];
    long long  llg[10];
    float ft[10];
    double db[10];
    decimal dl[10];

    /* 字符串类型 */
    char val[10][10];
    varchar vc[10][10];
    bytea  ba[10][10];
    char  c[10];
    string str_value[10];

    /* 时间类型 */
    timestamp ts[10];
    date d[10];
    interval inter[10];

    /* 布尔类型 */
    bool bl[10];
};

exec sql end declare section;

static void
print_sqlca()
{
    fprintf(stderr, "==== sqlca ====\n");
    fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
    fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
    fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
    fprintf(stderr, "===============\n");
}

int main() 
{
    /* 声明主变量 */
	exec sql begin declare section;
    union u_mixed_statements uoda;
    int i = 0;
	exec sql end declare section;

    /* 打开一个调试日志 */
	ECPGdebug(1, stderr);

	/* 连接数据库 */
	EXEC SQL CONNECT TO oracledb;

	/* 设置 waring 和 error 的处理方式 */
	EXEC SQL WHENEVER SQLWARNING SQLPRINT;
	EXEC SQL WHENEVER SQLERROR CALL print_sqlca(); 

	/* -----------------------union混合数组插入数据----------------------- */
    {
        /* -----------------int类型测试----------------- */
        {
            for(i = 0; i < 10; i++)
            {
                uoda.v_error_no[i] = i + 1;
            }

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k1) values
            (:uoda.v_error_no);

	        EXEC SQL WHENEVER SQLERROR continue;
            i = 2;
            EXEC SQL for :i update test_for_count set k1 = :uoda.v_error_no where k1 = uoda.v_error_no[1];
            fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }
    }
    /* 断开连接 */
	exec sql disconnect;

	return 0;
}

异常测试2

编译失败

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

EXEC SQL INCLUDE ../regression;
exec sql include ../../preproc/type.h;
#include <pgtypes_date.h>
#include <pgtypes_interval.h>
#include <pgtypes_numeric.h>
#include <pgtypes_timestamp.h>

exec sql type string is char[11];
typedef char string[11];

exec sql begin declare section;

union u_mixed_statements
{
    /* 数值类型数值 */
	int v_error_no[10];
    numeric n[10];
    short st[10];
    long lg[10];
    long long  llg[10];
    float ft[10];
    double db[10];
    decimal dl[10];

    /* 字符串类型 */
    char val[10][10];
    varchar vc[10][10];
    bytea  ba[10][10];
    char  c[10];
    string str_value[10];

    /* 时间类型 */
    timestamp ts[10];
    date d[10];
    interval inter[10];

    /* 布尔类型 */
    bool bl[10];
};

exec sql end declare section;

static void
print_sqlca()
{
    fprintf(stderr, "==== sqlca ====\n");
    fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
    fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
    fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
    fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
    fprintf(stderr, "===============\n");
}

int main() 
{
    /* 声明主变量 */
	exec sql begin declare section;
    union u_mixed_statements uoda;
    int i = 0;
	exec sql end declare section;

    /* 打开一个调试日志 */
	ECPGdebug(1, stderr);

	/* 连接数据库 */
	EXEC SQL CONNECT TO oracledb;

	/* 设置 waring 和 error 的处理方式 */
	EXEC SQL WHENEVER SQLWARNING SQLPRINT;
	EXEC SQL WHENEVER SQLERROR CALL print_sqlca();

	/* -----------------------union混合数组插入数据----------------------- */
    {
        /* -----------------char类型测试----------------- */
        /* 针对数据库表类型为char */
        {
            memcpy(uoda.c, "11111111\n", 10);

            /* 建表 */
            exec sql create table test_for_count(
                k1 integer,
                k2 char(10),
                k3 numeric,
                k4 timestamp,
                k5 date,
                k6 smallint,
                k7 bigint,
                k8 bigint,
                k9 real,
                k10 double precision,
                k11 bool,
                k12 varchar(100),
                k13 bytea,
                k14 text,
                k15 char,
                k16 decimal,
                k17 interval);

            i = 3;
            EXEC SQL for :i insert into test_for_count(k15) values
            (:uoda.c);

            i = 2;
            EXEC SQL for :i update test_for_count set k15 = :uoda.c where k15 = :uoda.c[1];
            fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);

            /* 清理环境 */
            EXEC SQL DROP table test_for_count;
        }
    }
    /* 断开连接 */
	exec sql disconnect;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值