LightDB24.1 ecpg支持exec sql for :i update(or insert)语法

news2024/10/6 10:34:21

背景

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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1579397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

diffusion model(十五) : IP-Adapter技术小结

infopaperhttps://arxiv.org/pdf/2308.06721.pdfcodehttps://github.com/tencent-ailab/IP-Adapterorg.Tencent AI Lab个人博客地址http://myhz0606.com/article/ip_adapter 1 Motivation 为了对文生图diffusion model进行特定概念的定制&#xff0c;常用LoRA[1]、textual in…

国内超声波清洗机排名!洗眼镜超声波清洗机推荐

眼镜是我们日常生活中不可或缺的用具&#xff0c;但随着使用时间的增长&#xff0c;眼镜上的灰尘和污垢也会逐渐积累&#xff0c;传统的清洗方法往往难以彻底清洁。为了解决这一难题&#xff0c;超声波清洗机出现了&#xff01;它利用超声波振动原理&#xff0c;可以轻松、快速…

使用Docker部署jar包

vi DockerfileDockerfile内容 FROM java:8 ADD chery5G-admin.jar chery5G-admin.jar ENTRYPOINT ["java","-jar","chery5G-admin.jar"]上传jar包到Dockerfile文件同级目录 使用Dockerfile文件&#xff0c;将jar包制作为镜像 docker build -t…

2024/4/5—力扣—在排序数组中查找元素的第一个和最后一个位置

代码实现&#xff1a; 思路&#xff1a;二分法 方法一&#xff1a;分别查找左右侧边界 /*** Note: The returned array must be malloced, assume caller calls free().*/ int GetTargetFirstPosition(int *nums, int numsSize, int target) {int l 0, r numsSize - 1;while …

JAVA面试八股文之Redis相关

Redis相关 Redis6.0为什么要用多线程&#xff1f;在Redis中存一个list集合怎么实现排序&#xff1f;Redis的5大基本类型的底层原理&#xff1f;缓存穿透&#xff1f;缓存击穿&#xff1f;缓存雪崩&#xff1f;redis做为缓存怎么保持和mysql数据进行同步&#xff1f;&#xff08…

物证管理系统|DW-S404实现物证全生命周期管理

物证管理系统|DW-S404实现物证全生命周期管理 一、项目背景 随着社会的进步和科技的发展&#xff0c;信息化和数字化已经成为各个行业的必然趋势。在众多领域中&#xff0c;物证管理系统逐渐受到广泛的关注和应用。 物证是公安机关处理案件的关键凭证&#xff0c;针对过去物证管…

如何给MySQL数据库的所有表统一加上字段

在开发过程中&#xff0c;有时候慢慢的建了很多数据库表&#xff0c;但是后来发现需要统一增加某些字段的时候&#xff0c;可以通过alter语句 ALTER TABLE 表名 ADD 列名 数据类型;比如我要给t_user表增加gmt_create与gmt_modified字段&#xff0c;用作记录新增记录时间与更新…

U盘格式化数据恢复,3个妙计助你快速恢复!

“我的u盘由于中病毒了&#xff0c;我不得已将它格式化了&#xff0c;现在想进行u盘数据的恢复&#xff0c;不知道应该怎么操作&#xff0c;大家有什么方法推荐吗&#xff1f;” U盘作为我们日常生活中常见的存储设备&#xff0c;经常用于存储各种重要数据。但是在日常使用u盘的…

华火电火灶:人间烟火味,最抚凡人心

厨房&#xff0c;一直是家的核心&#xff0c;那里不仅有妈妈的味道&#xff0c;更有生活的味道。当炊烟袅袅&#xff0c;炉火旺盛&#xff0c;家的温馨与幸福便油然而生。华火电火灶以其独特的魅力&#xff0c;不仅成为了现代厨房中的一道亮丽风景线&#xff0c;更成为了家人的…

Digicert 证书

一、简介 在当今数字化时代&#xff0c;网络安全已成为全球关注的焦点。随着网络攻击和数据泄露事件的频发&#xff0c;企业和组织越来越重视保护自己的网络环境。在这种背景下&#xff0c;数字证书成为了确保网络通信安全的关键工具。作为数字证书行业的领导者&#xff0c;Di…

yolov8草莓及病害检测项目开发(python开发,带有训练模型,可以重新训练,并有Pyqt5界面可视化)

本次检测系统&#xff0c;可以通过图片、视频或摄像头三种形式检测&#xff0c;检测出开花、结果、熟果、草莓叶子健康、叶子缺钙、灰叶斑病等八大类别。基于最新的YOLO-v8模型&#xff0c;下载后即可重新运行训练脚本&#xff0c;&#xff0c;也可以直接运行检测脚本&#xff…

嘉轩智能工业科技诚邀您参观2024第13届生物发酵展

参展企业介绍 自2005年成立以来&#xff0c;嘉轩一直致力于工业智能永磁滚筒的研发、制造及销售&#xff0c;具有十多年的从业经验&#xff0c;公司主营产品包括工业智能永磁滚筒、机电智能诊断、工业智能电机等&#xff0c;高效智能自驱动永磁滚筒为我公司目前主导产品&#x…

考PMP一定要培训吗?PMP备考可不是说着玩的

想要考项目管理认证一定要培训吗&#xff1f;其实这是必要的也是必须的啦&#xff0c;不仅仅是因为自学的难度大&#xff0c;个人自学很难总结学习技巧&#xff0c;另一个原因就是考试前还必须要有授权培训机构提供的35学时培训证明&#xff0c;没有这个培训证明也就直接意味着…

使用 Go-Ora 连接到 Oracle 数据库

前文 《 一鍵啓動 Oracle 23c Free 》 介绍了如何使用容器技术快速拉起 Oracle 23c 数据库。 这个开发者版本可以很便捷的拉起、测试、销毁&#xff0c;对开发者是非常友好的。 本文将介绍如何使用 Go 语言构建项目&#xff0c;并连接到 Oracle 数据库。 Go 环境配置 本文使用的…

计算机视觉之三维重建(7)---多视图几何(下)

文章目录 一、透视结构恢复问题1.1 概述1.2 透视结构恢复歧义1.3 代数方法1.4 捆绑调整 二、P3P问题三、随机采样一致性 一、透视结构恢复问题 1.1 概述 1. 透视结构恢复问题&#xff1a;摄像机为透视相机&#xff0c;内外参数均未知。 2. 问题&#xff1a;已知 n n n 个三维…

一起学习python——基础篇(10)

前言&#xff0c;Python 是一种面向对象的编程语言。以前大学读书的时候经常开玩笑说的一句话“如果没有对象&#xff0c;就new一个”。起因就是编程老师上课时经常说一句“首先&#xff0c;我们new一个对象”。 今天讲一下python的类和对象。 类是什么&#xff1f;它是一种用…

互联网大厂ssp面经之路:计算机网络part2

什么是 HTTP 和 HTTPS&#xff1f;它们之间有什么区别&#xff1f; a. HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;安全超文本传输协议&#xff09;是用于在Web上传输数据的协议。它们之间的区别在于安全性和数据传输方式。 b. HTTP是一种不安全的协议&…

重大利好|五万亿元增量!能源领域大规模设备更新!

前 3月13日&#xff0c;国务院印发《推动大规模设备更新和消费品以旧换新行动方案》。国家发改委主任郑栅洁更是表示&#xff0c;随着高质量发展的深入推进&#xff0c;设备更新的需求会不断扩大&#xff0c;初步估算这是一个5万亿元以上的巨大市场。 在推进重点行业设备更新改…

面试算法-160-合并两个有序链表

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 解 class Solution {public ListNode mergeTwoLists(ListNode li…

Springboot-redis整合

Springboot-redis命令行封装 前言 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;即远程字典服务&#xff0c;是一个开源的使用ANSI C语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。Redis也是现…