| #include <locale.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| EXEC SQL WHENEVER SQLERROR SQLPRINT; |
| |
| EXEC SQL INCLUDE sqlca; |
| EXEC SQL INCLUDE ../regression; |
| |
| #define ARRAY_SIZE 2 |
| |
| void execute_test(void); |
| void commitTable(void); |
| void reset(void); |
| void printResult(char *tc_name, int loop); |
| |
| EXEC SQL BEGIN DECLARE SECTION; |
| int f1[ARRAY_SIZE]; |
| int f2[ARRAY_SIZE]; |
| char f3[ARRAY_SIZE][20]; |
| EXEC SQL END DECLARE SECTION; |
| |
| int main(void) |
| { |
| setlocale(LC_ALL, "C"); |
| |
| ECPGdebug(1, stderr); |
| |
| EXEC SQL CONNECT TO REGRESSDB1 AS con1; |
| EXEC SQL CONNECT TO REGRESSDB2 AS con2; |
| |
| EXEC SQL AT con1 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20)); |
| EXEC SQL AT con2 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20)); |
| |
| EXEC SQL AT con1 INSERT INTO source VALUES(1, 10, 'db on con1'); |
| EXEC SQL AT con1 INSERT INTO source VALUES(2, 20, 'db on con1'); |
| |
| EXEC SQL AT con2 INSERT INTO source VALUES(1, 10, 'db on con2'); |
| EXEC SQL AT con2 INSERT INTO source VALUES(2, 20, 'db on con2'); |
| |
| commitTable(); |
| |
| execute_test(); |
| |
| EXEC SQL AT con1 DROP TABLE IF EXISTS source; |
| EXEC SQL AT con2 DROP TABLE IF EXISTS source; |
| |
| commitTable(); |
| |
| EXEC SQL DISCONNECT ALL; |
| |
| return 0; |
| } |
| |
| /* |
| * default connection: con2 |
| * Non-default connection: con1 |
| * |
| */ |
| void execute_test(void) |
| { |
| EXEC SQL BEGIN DECLARE SECTION; |
| int i, count, length; |
| char *selectString = "SELECT f1,f2,f3 FROM source"; |
| EXEC SQL END DECLARE SECTION; |
| |
| /* |
| * testcase1. using DECLARE STATEMENT without using AT clause, |
| * using PREPARE and CURSOR statement without using AT clause |
| */ |
| reset(); |
| |
| EXEC SQL DECLARE stmt_1 STATEMENT; |
| EXEC SQL PREPARE stmt_1 FROM :selectString; |
| EXEC SQL DECLARE cur_1 CURSOR FOR stmt_1; |
| EXEC SQL OPEN cur_1; |
| |
| EXEC SQL WHENEVER NOT FOUND DO BREAK; |
| i = 0; |
| while (1) |
| { |
| EXEC SQL FETCH cur_1 INTO :f1[i], :f2[i], :f3[i]; |
| i++; |
| } |
| EXEC SQL CLOSE cur_1; |
| EXEC SQL DEALLOCATE PREPARE stmt_1; |
| EXEC SQL WHENEVER NOT FOUND CONTINUE; |
| |
| printResult("testcase1", 2); |
| |
| |
| /* |
| * testcase2. using DECLARE STATEMENT at con1, |
| * using PREPARE and CURSOR statement without using AT clause |
| */ |
| reset(); |
| |
| EXEC SQL AT con1 DECLARE stmt_2 STATEMENT; |
| EXEC SQL PREPARE stmt_2 FROM :selectString; |
| EXEC SQL DECLARE cur_2 CURSOR FOR stmt_2; |
| EXEC SQL OPEN cur_2; |
| |
| EXEC SQL WHENEVER NOT FOUND DO BREAK; |
| i = 0; |
| while (1) |
| { |
| EXEC SQL FETCH cur_2 INTO :f1[i], :f2[i], :f3[i]; |
| i++; |
| } |
| EXEC SQL CLOSE cur_2; |
| EXEC SQL DEALLOCATE PREPARE stmt_2; |
| EXEC SQL WHENEVER NOT FOUND CONTINUE; |
| |
| printResult("testcase2", 2); |
| |
| /* |
| * testcase3. using DECLARE STATEMENT without using AT clause, |
| * using PREPARE and EXECUTE statement without using AT clause |
| */ |
| reset(); |
| |
| EXEC SQL DECLARE stmt_3 STATEMENT; |
| EXEC SQL PREPARE stmt_3 FROM :selectString; |
| EXEC SQL EXECUTE stmt_3 INTO :f1, :f2, :f3; |
| |
| EXEC SQL DEALLOCATE PREPARE stmt_3; |
| |
| printResult("testcase3", 2); |
| |
| /* |
| * testcase4. using DECLARE STATEMENT without using AT clause, |
| * using PREPARE and CURSOR statement at con2 |
| */ |
| reset(); |
| |
| EXEC SQL DECLARE stmt_4 STATEMENT; |
| EXEC SQL AT con2 PREPARE stmt_4 FROM :selectString; |
| EXEC SQL AT con2 DECLARE cur_4 CURSOR FOR stmt_4; |
| EXEC SQL AT con2 OPEN cur_4; |
| |
| EXEC SQL WHENEVER NOT FOUND DO BREAK; |
| i = 0; |
| while (1) |
| { |
| EXEC SQL AT con2 FETCH cur_4 INTO :f1[i], :f2[i], :f3[i]; |
| i++; |
| } |
| EXEC SQL AT con2 CLOSE cur_4; |
| EXEC SQL AT con2 DEALLOCATE PREPARE stmt_4; |
| EXEC SQL WHENEVER NOT FOUND CONTINUE; |
| |
| printResult("testcase4", 2); |
| |
| /* |
| * DESCRIBE statement is also supported. |
| */ |
| EXEC SQL AT con1 DECLARE stmt_desc STATEMENT; |
| EXEC SQL PREPARE stmt_desc FROM :selectString; |
| EXEC SQL DECLARE cur_desc CURSOR FOR stmt_desc; |
| EXEC SQL OPEN cur_desc; |
| |
| /* descriptor can be used for describe statement */ |
| EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_describe; |
| EXEC SQL DESCRIBE stmt_desc INTO SQL DESCRIPTOR desc_for_describe; |
| |
| EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe :count = COUNT; |
| EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe VALUE 3 :length = LENGTH; |
| |
| EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_describe; |
| |
| /* for fetch statement */ |
| EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_fetch; |
| EXEC SQL FETCH cur_desc INTO SQL DESCRIPTOR desc_for_fetch; |
| |
| EXEC SQL AT con1 GET DESCRIPTOR desc_for_fetch VALUE 3 :f3[0] = DATA; |
| |
| EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_fetch; |
| EXEC SQL CLOSE cur_desc; |
| EXEC SQL DEALLOCATE stmt_desc; |
| |
| printf("****descriptor results****\n"); |
| printf("count: %d, length: %d, data: %s\n", count, length, f3[0]); |
| } |
| |
| void commitTable() |
| { |
| EXEC SQL AT con1 COMMIT; |
| EXEC SQL AT con2 COMMIT; |
| } |
| |
| /* |
| * reset all the output variables |
| */ |
| void reset() |
| { |
| memset(f1, 0, sizeof(f1)); |
| memset(f2, 0, sizeof(f2)); |
| memset(f3, 0, sizeof(f3)); |
| } |
| |
| void printResult(char *tc_name, int loop) |
| { |
| int i; |
| |
| if (tc_name) |
| printf("****%s test results:****\n", tc_name); |
| |
| for (i = 0; i < loop; i++) |
| printf("f1=%d, f2=%d, f3=%s\n", f1[i], f2[i], f3[i]); |
| |
| printf("\n"); |
| } |