Commit 6bccf64d authored by Marc G. Fournier's avatar Marc G. Fournier

From: Michael Meskes <meskes@topsystem.de>

Tue Apr 28 14:48:41 CEST 1998

      - Put operator "->" back into parser. Note that :foo->bar means the
        C term, but :foo ->bar means the operator "->".

Tue Apr 28 15:49:07 CEST 1998

      - Added exec sql disconnect command.
      - Allow varchar in C to be written in uppercase too.
      - Added whenever option "do break;"

Wed Apr 29 09:17:53 CEST 1998

      - Corrected parsing of C comments.
      - Also allow C++ style comments.
      - Make sure not found is only checked after commands that could
          return it.
      - Added error codes, see ecpgerror.h for details.
      - Added "exec sql <TransactionStmt> release" as disconnect statement
        for compatibility issues.

Thu Apr 30 10:42:10 CEST 1998

      - Added a -t option to disable automatic transaction start.
      - Added sqlerrd[] to sqlca struct.
      - Give back number of tuples affect in sqlca.sqlerrd[2].

Thu Apr 30 13:36:02 CEST 1998

      - Make the return code different in case of different errors.

Wed May  6 11:42:48 CEST 1998

      - Free memory if possible
      - Some bugfixes for bugs I found while changing the memory
          allocation code
      - Now able to fill complete array with one call (see test1.pgc for
          an example)
      - Set version to 2.3.0
      - Set library version to 2.1
parent f9322c66
...@@ -149,3 +149,43 @@ Mon Apr 27 14:26:55 CEST 1998 ...@@ -149,3 +149,43 @@ Mon Apr 27 14:26:55 CEST 1998
and :foo.bar as variables. and :foo.bar as variables.
- Set version to 2.2.0 - Set version to 2.2.0
Tue Apr 28 14:48:41 CEST 1998
- Put operator "->" back into parser. Note that :foo->bar means the
C term, but :foo ->bar means the operator "->".
Tue Apr 28 15:49:07 CEST 1998
- Added exec sql disconnect command.
- Allow varchar in C to be written in uppercase too.
- Added whenever option "do break;"
Wed Apr 29 09:17:53 CEST 1998
- Corrected parsing of C comments.
- Also allow C++ style comments.
- Make sure not found is only checked after commands that could
return it.
- Added error codes, see ecpgerror.h for details.
- Added "exec sql <TransactionStmt> release" as disconnect statement
for compatibility issues.
Thu Apr 30 10:42:10 CEST 1998
- Added a -t option to disable automatic transaction start.
- Added sqlerrd[] to sqlca struct.
- Give back number of tuples affect in sqlca.sqlerrd[2].
Thu Apr 30 13:36:02 CEST 1998
- Make the return code different in case of different errors.
Wed May 6 11:42:48 CEST 1998
- Free memory if possible
- Some bugfixes for bugs I found while changing the memory
allocation code
- Now able to fill complete array with one call (see test1.pgc for
an example)
- Set version to 2.3.0
- Set library version to 2.1
This list is still from Linus. MM
The variables should be static.
There should be different error numbers for the different errors instead of
just -1 for them all.
Missing library functions to_date et al.
Oracle has array operations that enhances speed. When implementing it in
ecpg it is done for compatibility reasons only. For them to improve speed
would require a lot more insight in the postgres internal mechanisms than I
possess.
As well as complex types like records and arrays, typedefs would be a good
thing to take care of.
To set up a database you need a few scripts with table definitions and other
configuration parameters. If you have these scripts for an old database you
would like to just apply them to get a postgres database that works in the
same way. The functionality could be accomplished with some conversion
scripts. Speed will never be accomplished in this way. To do this you need a
bigger insight in the database construction and the use of the database than
could be realised in a script.
Now comes my list (MM):
The return code is alway -1 in case of an error. You cannot see which error
occured by examining the return code.
ecpg does not understand enum datatypes. ecpg does not understand enum datatypes.
There is no exec sql prepare statement.
The complete structure definition has to be listed inside the declare The complete structure definition has to be listed inside the declare
section for ecpg to be able to understand it. section of the structure variable for ecpg to be able to understand it.
There is no way yet to fill a complete array with one call except arrays of Variable type bool has to be checked. I never used it so far.
[unsigned] char which are considered strings.
ecpg cannot use pointer variables except [unsigned] char * ecpg cannot use pointer variables except [unsigned] char *
give back the number of tuples affected via sqlca There is no exec sql type statement which is the SQL version of a typedef.
exec sql disconnect {current|default|all|connectionname|connection_hostvar}; There is no exec sql prepare statement.
oder <disconnect statement> ::=
DISCONNECT <disconnect object>
<disconnect object> ::=
<connection object>
| ALL
| CURRENT
commit release|commit work release auch disconnect
It is not neccessary to check for "not found" after all commands. There is no SQLSTATE
...@@ -6,11 +6,13 @@ all clean:: ...@@ -6,11 +6,13 @@ all clean::
@echo Nothing to be done. @echo Nothing to be done.
install:: install::
$(INSTALL) $(INSTLOPTS) ecpgerrno.h $(DESTDIR)$(HEADERDIR)
$(INSTALL) $(INSTLOPTS) ecpglib.h $(DESTDIR)$(HEADERDIR) $(INSTALL) $(INSTLOPTS) ecpglib.h $(DESTDIR)$(HEADERDIR)
$(INSTALL) $(INSTLOPTS) ecpgtype.h $(DESTDIR)$(HEADERDIR) $(INSTALL) $(INSTLOPTS) ecpgtype.h $(DESTDIR)$(HEADERDIR)
$(INSTALL) $(INSTLOPTS) sqlca.h $(DESTDIR)$(HEADERDIR) $(INSTALL) $(INSTLOPTS) sqlca.h $(DESTDIR)$(HEADERDIR)
uninstall:: uninstall::
rm -f $(DESTDIR)$(HEADERDIR)/ecpgerrno.h
rm -f $(DESTDIR)$(HEADERDIR)/ecpglib.h rm -f $(DESTDIR)$(HEADERDIR)/ecpglib.h
rm -f $(DESTDIR)$(HEADERDIR)/ecpgtype.h rm -f $(DESTDIR)$(HEADERDIR)/ecpgtype.h
rm -f $(DESTDIR)$(HEADERDIR)/sqlca.h rm -f $(DESTDIR)$(HEADERDIR)/sqlca.h
......
#ifndef _ECPG_ERROR_H
#define _ECPG_ERROR_H
/* This is a list of all error codes the embedded SQL program can return */
#define ECPG_NO_ERROR 0
#define ECPG_NOT_FOUND 100
#define ECPG_PGSQL -1
#define ECPG_UNSUPPORTED -2
#define ECPG_TOO_MANY_ARGUMENTS -3
#define ECPG_TOO_FEW_ARGUMENTS -4
#define ECPG_TRANS -5
#define ECPG_TOO_MANY_MATCHES -6
#define ECPG_INT_FORMAT -7
#define ECPG_UINT_FORMAT -8
#define ECPG_FLOAT_FORMAT -9
#define ECPG_CONVERT_BOOL -10
#define ECPG_EMPTY -11
#define ECPG_CONNECT -12
#define ECPG_DISCONNECT -13
#endif /* !_ECPG_ERROR_H */
...@@ -5,11 +5,11 @@ extern "C" { ...@@ -5,11 +5,11 @@ extern "C" {
#endif #endif
void ECPGdebug(int, FILE *); void ECPGdebug(int, FILE *);
bool ECPGconnect(const char *dbname); bool ECPGconnect(const char *);
bool ECPGdo(int, char *,...); bool ECPGdo(int, char *,...);
bool ECPGtrans(int, const char *); bool ECPGtrans(int, const char *);
bool ECPGfinish(void); bool ECPGfinish(void);
bool ECPGstatus(void); bool ECPGdisconnect(const char *);
void ECPGlog(const char *format,...); void ECPGlog(const char *format,...);
...@@ -39,3 +39,5 @@ void sqlprint(void); ...@@ -39,3 +39,5 @@ void sqlprint(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#include <ecpgerrno.h>
...@@ -10,10 +10,11 @@ struct sqlca ...@@ -10,10 +10,11 @@ struct sqlca
int sqlcode; int sqlcode;
struct struct
{ {
int sqlerrml; int sqlerrml;
char sqlerrmc[1000]; char sqlerrmc[1000];
} sqlerrm; } sqlerrm;
} sqlca; long sqlerrd[6];
} sqlca;
#endif #endif
......
...@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global ...@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
SO_MAJOR_VERSION=2 SO_MAJOR_VERSION=2
SO_MINOR_VERSION=0 SO_MINOR_VERSION=1
PORTNAME=@PORTNAME@ PORTNAME=@PORTNAME@
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ SRCDIR= ../../.. ...@@ -2,7 +2,7 @@ SRCDIR= ../../..
include $(SRCDIR)/Makefile.global include $(SRCDIR)/Makefile.global
MAJOR_VERSION=2 MAJOR_VERSION=2
MINOR_VERSION=2 MINOR_VERSION=3
PATCHLEVEL=0 PATCHLEVEL=0
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \ CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
static ScanKeyword ScanKeywords[] = { static ScanKeyword ScanKeywords[] = {
/* name value */ /* name value */
{"VARCHAR", S_VARCHAR},
{"auto", S_AUTO}, {"auto", S_AUTO},
{"bool", S_BOOL}, {"bool", S_BOOL},
{"char", S_CHAR}, {"char", S_CHAR},
......
...@@ -22,12 +22,13 @@ extern char *optarg; ...@@ -22,12 +22,13 @@ extern char *optarg;
#include "extern.h" #include "extern.h"
struct _include_path *include_paths; struct _include_path *include_paths;
static int no_auto_trans = 0;
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL); fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "Usage: %s: [-v] [-I include path] [ -o output file name] file1 [file2] ...\n", progname); fprintf(stderr, "Usage: %s: [-v] [-t] [-I include path] [ -o output file name] file1 [file2] ...\n", progname);
} }
static void static void
...@@ -51,7 +52,7 @@ main(int argc, char *const argv[]) ...@@ -51,7 +52,7 @@ main(int argc, char *const argv[])
add_include_path("/usr/local/include"); add_include_path("/usr/local/include");
add_include_path("."); add_include_path(".");
while ((c = getopt(argc, argv, "vo:I:")) != EOF) while ((c = getopt(argc, argv, "vo:I:t")) != EOF)
{ {
switch (c) switch (c)
{ {
...@@ -65,23 +66,26 @@ main(int argc, char *const argv[]) ...@@ -65,23 +66,26 @@ main(int argc, char *const argv[])
case 'I': case 'I':
add_include_path(optarg); add_include_path(optarg);
break; break;
case 't':
no_auto_trans = 1;
break;
case 'v': case 'v':
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL); fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "exec sql include ... search starts here:\n"); fprintf(stderr, "exec sql include ... search starts here:\n");
for (ip = include_paths; ip != NULL; ip = ip->next) for (ip = include_paths; ip != NULL; ip = ip->next)
fprintf(stderr, " %s\n", ip->path); fprintf(stderr, " %s\n", ip->path);
fprintf(stderr, "End of search list.\n"); fprintf(stderr, "End of search list.\n");
return (0); return (OK);
default: default:
usage(argv[0]); usage(argv[0]);
return (1); return (ILLEGAL_OPTION);
} }
} }
if (optind >= argc) /* no files specified */ if (optind >= argc) /* no files specified */
{ {
usage(argv[0]); usage(argv[0]);
return(1); return(ILLEGAL_OPTION);
} }
else else
{ {
...@@ -151,8 +155,8 @@ main(int argc, char *const argv[]) ...@@ -151,8 +155,8 @@ main(int argc, char *const argv[])
cur = NULL; cur = NULL;
/* we need two includes */ /* we need two includes and a constant */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL); fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans);
/* and parse the source */ /* and parse the source */
yyparse(); yyparse();
...@@ -169,5 +173,5 @@ main(int argc, char *const argv[]) ...@@ -169,5 +173,5 @@ main(int argc, char *const argv[])
free(input_filename); free(input_filename);
} }
} }
return (0); return (OK);
} }
...@@ -21,15 +21,18 @@ ...@@ -21,15 +21,18 @@
*/ */
static ScanKeyword ScanKeywords[] = { static ScanKeyword ScanKeywords[] = {
/* name value */ /* name value */
{"break", SQL_BREAK},
{"call", SQL_CALL}, {"call", SQL_CALL},
{"connect", SQL_CONNECT}, {"connect", SQL_CONNECT},
{"continue", SQL_CONTINUE}, {"continue", SQL_CONTINUE},
{"disconnect", SQL_DISCONNECT},
{"found", SQL_FOUND}, {"found", SQL_FOUND},
{"go", SQL_GO}, {"go", SQL_GO},
{"goto", SQL_GOTO}, {"goto", SQL_GOTO},
{"immediate", SQL_IMMEDIATE}, {"immediate", SQL_IMMEDIATE},
{"indicator", SQL_INDICATOR}, {"indicator", SQL_INDICATOR},
{"open", SQL_OPEN}, {"open", SQL_OPEN},
{"release", SQL_RELEASE},
{"section", SQL_SECTION}, {"section", SQL_SECTION},
{"sqlerror", SQL_SQLERROR}, {"sqlerror", SQL_SQLERROR},
{"sqlprint", SQL_SQLPRINT}, {"sqlprint", SQL_SQLPRINT},
......
...@@ -43,3 +43,11 @@ extern void *mm_alloc(size_t), *mm_realloc(void *, size_t); ...@@ -43,3 +43,11 @@ extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
ScanKeyword * ScanECPGKeywordLookup(char *); ScanKeyword * ScanECPGKeywordLookup(char *);
ScanKeyword * ScanCKeywordLookup(char *); ScanKeyword * ScanCKeywordLookup(char *);
extern void yyerror(char *); extern void yyerror(char *);
/* return codes */
#define OK 0
#define NO_INCLUDE_FILE 1
#define PARSE_ERROR 2
#define OUT_OF_MEMORY 3
#define ILLEGAL_OPTION 4
...@@ -39,6 +39,7 @@ int debugging = 0; ...@@ -39,6 +39,7 @@ int debugging = 0;
extern YYSTYPE yylval; extern YYSTYPE yylval;
int llen; int llen;
char literal[MAX_PARSE_BUFFER]; char literal[MAX_PARSE_BUFFER];
int before_comment;
struct _yy_buffer { YY_BUFFER_STATE buffer; struct _yy_buffer { YY_BUFFER_STATE buffer;
long lineno; long lineno;
...@@ -153,7 +154,7 @@ space [ \t\n\f] ...@@ -153,7 +154,7 @@ space [ \t\n\f]
other . other .
/* some stuff needed for ecpg */ /* some stuff needed for ecpg */
ccomment \/\*([^*]|\*[^/]|\*\*[^/])*\*\/ ccomment "//".*\n
exec [eE][xX][eE][cC] exec [eE][xX][eE][cC]
include [iI][nN][cC][lL][uU][dD][eE] include [iI][nN][cC][lL][uU][dD][eE]
sql [sS][qQ][lL] sql [sS][qQ][lL]
...@@ -174,12 +175,18 @@ sql [sS][qQ][lL] ...@@ -174,12 +175,18 @@ sql [sS][qQ][lL]
%% %%
<SQL>{comment} { /* ignore */ } <SQL>{comment} { /* ignore */ }
<SQL>{xcline} { /* ignore */ } {xcline} { /* ignore */ }
<xc>{xcstar} | <xc>{xcstar} { /* ignore */ }
<SQL>{xcstart} { BEGIN(xc); } {xcstart} {
fprintf(stderr,"ys = %d %d\n", YYSTATE, before_comment);
before_comment = YYSTATE;
BEGIN(xc);
fprintf(stderr,"ys = %d %d\n", YYSTATE,
before_comment);
}
<xc>{xcstop} { BEGIN(SQL); } <xc>{xcstop} { fprintf(stderr,"ys = %d %d\n", YYSTATE, before_comment);BEGIN(before_comment); }
<xc>{xcinside} { /* ignore */ } <xc>{xcinside} { /* ignore */ }
...@@ -306,7 +313,6 @@ sql [sS][qQ][lL] ...@@ -306,7 +313,6 @@ sql [sS][qQ][lL]
return (yytext[0]); return (yytext[0]);
} }
<SQL>{self} { return (yytext[0]); } <SQL>{self} { return (yytext[0]); }
<SQL>"->" { return S_STRUCTPOINTER; }
<SQL>{operator}/-[\.0-9] { <SQL>{operator}/-[\.0-9] {
yylval.str = strdup((char*)yytext); yylval.str = strdup((char*)yytext);
return (Op); return (Op);
...@@ -402,7 +408,7 @@ sql [sS][qQ][lL] ...@@ -402,7 +408,7 @@ sql [sS][qQ][lL]
return (FCONST); return (FCONST);
} }
<SQL>:{identifier} { <SQL>:{identifier}(("->"|\.){identifier})* {
yylval.str = strdup((char*)yytext+1); yylval.str = strdup((char*)yytext+1);
return(CVARIABLE); return(CVARIABLE);
} }
...@@ -436,6 +442,7 @@ sql [sS][qQ][lL] ...@@ -436,6 +442,7 @@ sql [sS][qQ][lL]
<SQL>{other} { return (yytext[0]); } <SQL>{other} { return (yytext[0]); }
<C>{exec}{space}{sql} { BEGIN SQL; return SQL_START; } <C>{exec}{space}{sql} { BEGIN SQL; return SQL_START; }
<C>{ccomment} { /* ignore */ }
<C>{identifier} { <C>{identifier} {
ScanKeyword *keyword; ScanKeyword *keyword;
...@@ -501,7 +508,7 @@ sql [sS][qQ][lL] ...@@ -501,7 +508,7 @@ sql [sS][qQ][lL]
if (!yyin) if (!yyin)
{ {
fprintf(stderr, "Error: Cannot open include file %s in line %d\n", yytext, yylineno); fprintf(stderr, "Error: Cannot open include file %s in line %d\n", yytext, yylineno);
exit(1); exit(NO_INCLUDE_FILE);
} }
input_filename = strdup(inc_file); input_filename = strdup(inc_file);
......
This diff is collapsed.
This diff is collapsed.
...@@ -77,6 +77,7 @@ struct when ...@@ -77,6 +77,7 @@ struct when
struct index struct index
{ {
int ival; int index1;
char *str; int index2;
char *str;
}; };
all: test2 perftest all: test1 test2 perftest
LDFLAGS=-g -I ../include -I ../../libpq -L../lib -lecpg -L../../libpq -lpq -lcrypt --static
test1: test1.c
test1.c: test1.pgc
../preproc/ecpg $?
test2: test2.c test2: test2.c
gcc -g -I ../include -I ../../libpq -o test2 test2.c -L../lib -lecpg -L../../libpq -lpq -lcrypt --static
test2.c: test2.pgc test2.c: test2.pgc
../preproc/ecpg test2.pgc ../preproc/ecpg $?
perftest: perftest.c perftest: perftest.c
gcc -g -I ../include -I ../../libpq -o perftest perftest.c -L../lib -lecpg -L../../libpq -lpq -lcrypt --static perftest.c:perftest.pgc
perftest.c: perftest.pgc ../preproc/ecpg $?
../preproc/ecpg perftest.pgc
clean: clean:
/bin/rm test2 test2.c perftest perftest.c log /bin/rm test1 test2 perftest *.c log
/* These two include files are added by the preprocessor */
#include <ecpgtype.h>
#include <ecpglib.h>
/* exec sql begin declare section */
/* VARSIZE */ struct varchar_uid
{
int len;
char arr[200];
} uid;
struct varchar_name
{
int len;
char arr[200];
} name;
short value;
/* exec sql end declare section */
#include "sqlca.h"
#define DBCP(x,y) strcpy(x.arr,y);x.len = strlen(x.arr)
#define LENFIX(x) x.len=strlen(x.arr)
#define STRFIX(x) x.arr[x.len]='\0'
#define SQLCODE sqlca.sqlcode
void
db_error(char *msg)
{
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
printf("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
exit(1);
}
int
main()
{
strcpy(uid.arr, "test/test");
LENFIX(uid);
ECPGconnect("kom");
if (SQLCODE)
db_error("connect");
strcpy(name.arr, "opt1");
LENFIX(name);
ECPGdo(__LINE__, "declare cur cursor for select name , value from pace_test ", ECPGt_EOIT, ECPGt_EORT);
if (SQLCODE)
db_error("declare");
if (SQLCODE)
db_error("open");
while (1)
{
ECPGdo(__LINE__, "fetch in cur ", ECPGt_EOIT, ECPGt_varchar, &name, 200, 0, sizeof(struct varchar_name), ECPGt_short, &value, 0, 0, sizeof(short), ECPGt_EORT);
if (SQLCODE)
break;
STRFIX(name);
printf("%s\t%d\n", name.arr, value);
}
if (SQLCODE < 0)
db_error("fetch");
ECPGdo(__LINE__, "close cur ", ECPGt_EOIT, ECPGt_EORT);
if (SQLCODE)
db_error("close");
ECPGcommit(__LINE__);
if (SQLCODE)
db_error("commit");
return (0);
}
exec sql include sqlca; exec sql include sqlca;
exec sql whenever not found do set_not_found(); exec sql whenever not found do break;
exec sql whenever sqlerror sqlprint; exec sql whenever sqlerror sqlprint;
...@@ -121,5 +121,7 @@ exec sql end declare section; ...@@ -121,5 +121,7 @@ exec sql end declare section;
exec sql commit; exec sql commit;
exec sql disconnect;
return (0); return (0);
} }
exec sql begin declare section;
VARCHAR uid[200 /* VARSIZE */ ];
varchar name[200];
short value;
exec sql end declare section;
exec sql include sqlca;
#define DBCP(x,y) strcpy(x.arr,y);x.len = strlen(x.arr)
#define LENFIX(x) x.len=strlen(x.arr)
#define STRFIX(x) x.arr[x.len]='\0'
#define SQLCODE sqlca.sqlcode
void
db_error(char *msg)
{
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
printf("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
exit(1);
}
int
main()
{
strcpy(uid.arr, "test/test");
LENFIX(uid);
exec sql connect 'kom';
if (SQLCODE)
db_error("connect");
strcpy(name.arr, "opt1");
LENFIX(name);
exec sql declare cur cursor for
select name,
value from pace_test;
if (SQLCODE)
db_error("declare");
exec sql open cur;
if (SQLCODE)
db_error("open");
while (1)
{
exec sql fetch in cur into:name,
: value;
if (SQLCODE)
break;
STRFIX(name);
printf("%s\t%d\n", name.arr, value);
}
if (SQLCODE < 0)
db_error("fetch");
exec sql close cur;
if (SQLCODE)
db_error("close");
exec sql commit;
if (SQLCODE)
db_error("commit");
return (0);
}
#include <stdio.h>
exec sql whenever sqlerror sqlprint;
exec sql include sqlca;
int
main ()
{
exec sql begin declare section;
int amount[5];
char name[5][8];
exec sql end declare section;
char msg[128], command[128];
FILE *dbgs;
int i,j;
if ((dbgs = fopen("log", "w")) != NULL)
ECPGdebug(1, dbgs);
strcpy(msg, "connect");
exec sql connect mm;
strcpy(msg, "create");
exec sql create table test(name char(8), amount int);
strcpy(msg, "execute insert 1");
sprintf(command, "insert into test(name, amount) values ('foobar', 1)");
exec sql execute immediate :command;
strcpy(msg, "excute insert 2");
sprintf(command, "insert into test(name, amount) select name, amount+1 from test");
exec sql execute immediate :command;
strcpy(msg, "excute insert 3");
sprintf(command, "insert into test(name, amount) select name, amount+10 from test");
exec sql execute immediate :command;
printf("Inserted %d tuples via execute immediate\n", sqlca.sqlerrd[2]);
strcpy(msg, "commit");
exec sql commit;
strcpy(msg, "select");
exec sql select name, amount into :name, :amount from test;
for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
printf("name[%d]=%8.8s, amount[%d]=%d\n", i, name[i], i, amount[i]);
strcpy(msg, "drop");
exec sql drop table test;
strcpy(msg, "commit");
exec sql commit;
strcpy(msg, "disconnect");
exec sql disconnect;
if (dbgs != NULL)
fclose(dbgs);
return (0);
}
...@@ -2,13 +2,6 @@ ...@@ -2,13 +2,6 @@
exec sql include header_test; exec sql include header_test;
static int not_found = 0;
static void
set_not_found(void)
{
not_found = 1;
}
int int
main () main ()
{ {
...@@ -43,10 +36,7 @@ exec sql end declare section; ...@@ -43,10 +36,7 @@ exec sql end declare section;
exec sql insert into meskes(name, born, age, married) values ('Michael', 19660117, 32, '19900404'); exec sql insert into meskes(name, born, age, married) values ('Michael', 19660117, 32, '19900404');
exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 7); exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 7);
exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 4); exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 4);
exec sql insert into meskes(name, born, age) values ('Chris', 19970923, 0);
sprintf(command, "insert into meskes(name, born, age) values ('Chris', 19970923, 0)");
strcpy(msg, "execute");
exec sql execute immediate :command;
strcpy(msg, "commit"); strcpy(msg, "commit");
exec sql commit; exec sql commit;
...@@ -58,11 +48,10 @@ exec sql end declare section; ...@@ -58,11 +48,10 @@ exec sql end declare section;
strcpy(msg, "open"); strcpy(msg, "open");
exec sql open cur; exec sql open cur;
while (not_found == 0) { while (1) {
strcpy(msg, "fetch"); strcpy(msg, "fetch");
exec sql fetch cur into :personal:ind_personal, :married:ind_married; exec sql fetch cur into :personal:ind_personal, :married:ind_married;
if (not_found == 0) printf ("%8.8s was born %d (age = %d) %s%s\n", personal.name.arr, personal.birth.born, personal.birth.age, ind_married ? "" : "and married ", ind_married ? "" : married);
printf ("%8.8s was born %d (age = %d) %s%s\n", personal.name.arr, personal.birth.born, personal.birth.age, ind_married ? "" : "and married ", ind_married ? "" : married);
} }
strcpy(msg, "close"); strcpy(msg, "close");
...@@ -74,6 +63,9 @@ exec sql end declare section; ...@@ -74,6 +63,9 @@ exec sql end declare section;
strcpy(msg, "commit"); strcpy(msg, "commit");
exec sql commit; exec sql commit;
strcpy(msg, "disconnect");
exec sql disconnect;
if (dbgs != NULL) if (dbgs != NULL)
fclose(dbgs); fclose(dbgs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment