Re: [Help Me] about dynamic sql?
Posted in 1998
HSY, you can use FETCH ABSOLUTE <:number> <cursor name> way down below in the FETCH statement. I have repeated your code and added my version. -- Jake HEO SI YOUNG wrote: > > I am developing the application program using IDS 7.23. > > In my application, i want to scroll cursor to retrive data with > arbitrary row numbers. > > How do i implement that? > First, i use the dynamic sql informix example file, and modify this > program. > and then i want to retrive data and send the client. > > pleas help me. > > program source. > > please teach me what to modify this program. > > ------------------------------------------------------------------------ > #ifndef lint > static char sccsid[] = "@(#) sql.ec 1.0 98/07/11 13:45:00"; > #endif /* not lint */ > > #include<stdio.h> > > EXEC SQL include sqlca ; > EXEC SQL include sqlstype ; > EXEC SQL include sqltypes ; > EXEC SQL include datetime ; > EXEC SQL include locator ; > > #define DESC_MAX 99 > #define INTWIDTH 8 > #define FLOATWIDTH 8 > #define FLOATPREC 2 > #define DTIMEWIDTH 25 > #define INTERVALWIDTH 20 > > #define sqlfatal() sqlfatal_loc(__FILE__,__LINE__) > #define fatal(s) fatal_loc(s,__FILE__,__LINE__) > > EXEC SQL begin declare section; > int d_max, nblobs; > char d_id[19]; > loc_t blobs[10]; > EXEC SQL end declare section; > > main() > { > char s[133],*cp; > d_max= DESC_MAX; > > /* Print copyright message */ > (void)fprintf(stderr, > "SQL version 1.0, Copyright (C) 1998 Si YOUNG HEO\\n\\n"); > > strcpy(d_id,"descname"); > > EXEC SQL allocate descriptor :d_id with max :d_max; sqlfatal(); > > while(1){ > > printf(" SQL> "); > cp=fgets(s,132,stdin); > > if(!cp) break; > if(*cp != '\\n'){ > if( !strcmp(s,"quit\\n")) break; > sql_process(s); > } > } > > EXEC SQL deallocate descriptor :d_id; sqlfatal(); > > exit(0); > } > > /* end of main function */ > > int > sql_process(s) > char *s; > { > EXEC SQL begin declare section; > int d_count; > char *cp; > EXEC SQL end declare section; > long type; > > cp = s; /* query statements */ > > EXEC SQL prepare pl_id from :cp; /* parsing and query plan */ > > if(SQLCODE) sqlnonfatal(); > > else { > EXEC SQL describe pl_id using sql descriptor :d_id ; > type=SQLCODE; > > EXEC SQL get descriptor :d_id :d_count=count; > sqlfatal(); > > if( 0 == type || SQ_EXECPROC == type ) > sql_select(d_count); > else { > if(d_count >0) > sql_values(d_count); > else > sql_execute(); > } > } > > > EXEC SQL free pl_id; > sqlfatal(); > } > /* end of sql_process() */ > > int > sql_select(d_count) > int d_count; > { > int n=0; > sql_blobinit(d_count); > > EXEC SQL declare cl_id cursor for pl_id; > sqlfatal(); > > EXEC SQL open cl_id; > sqlfatal(); > > while(1){ > EXEC SQL fetch cl_id using sql descriptor :d_id; /* *** BEGIN Jake's Commentary * Instead of above EXEC SQL, use the following. Assume recnum is a * host variable containing the record number of the row within the * active set. */ EXEC SQL fetch absolute :recnum cl_id using sql descriptor :d_id; /* * *** End Jake's Commentary */ > if(SQLCODE) break; > sql_showdesc(d_count); > } > > if(SQLCODE != SQLNOTFOUND) sqlfatal(); > > EXEC SQL close cl_id; > sqlfatal(); > > EXEC SQL free cl_id; > sqlfatal(); > > sql_blobfree(); > } > > /* end of sql_select function */ > > int > sql_blobinit(d_count) > int d_count; > { > EXEC SQL begin declare section; > int i; > short c_type; > EXEC SQL end declare section; > > nblobs=0; > > for(i=1; i<=d_count; ++i){ > > EXEC SQL get descriptor :d_id value :i :c_type =type; > sqlfatal(); > /* > if(c_type == SQLTEXT || c_type == SQLBYTE) { > */ > if(c_type == 11 || c_type == 12) { > blobs[nblobs].loc_loctype=LOCMEMORY; > blobs[nblobs].loc_bufsize=-1; > blobs[nblobs].loc_oflags=0; > EXEC SQL set descriptor > :d_id value :i data = :blobs[nblobs]; > sqlfatal(); > nblobs++; > } > } > } > > int > sql_blobfree() > { > while(nblobs--) > if(blobs[nblobs].loc_bufsize >0) > free(blobs[nblobs].loc_buffer); > } > > int > sql_showdesc(d_count) > int d_count; > { > > EXEC SQL begin declare section; > int col; > short c_length; > short c_type; > int c_ind; > int c_int; > long c_long; > float c_float; > double c_double; > dec_t c_dec; > dtime_t c_time; > intrvl_t c_interval; > loc_t c_loc; > char c_char[256]; > EXEC SQL end declare section; > > char tmpstr[30]; > char *cp; > int n; > int nb=0; > > for(col=1; col<=d_count; ++col){ > > EXEC SQL get descriptor :d_id value :col > :c_length=length, > :c_type=type, > :c_ind=indicator; > sqlfatal(); > > if( -1 == c_ind ) printf("<null>"); > else{ > > switch(c_type){ > > case SQLCHAR: > case SQLVCHAR: > EXEC SQL get descriptor :d_id value :col :c_char=data; > sqlfatal(); > printf("%-*s", (int) c_length, btrim(c_char)); > break; > > case SQLSMINT: > case SQLSERIAL: > EXEC SQL get descriptor :d_id > value :col :c_long=data; > sqlfatal(); > printf("%*ld", INTWIDTH, c_long); > break; > > case SQLDATE: > EXEC SQL get descriptor :d_id value :col :c_long=data; > sqlfatal(); > rdatestr(c_long,tmpstr); > printf("%s",tmpstr); > break; > > case SQLSMFLOAT: > EXEC SQL get descriptor :d_id value :col :c_float=data; > sqlfatal(); > printf("%*.*f",FLOATWIDTH, FLOATPREC,c_float); > break; > > case SQLFLOAT: > EXEC SQL get descriptor :d_id value :col :c_double=data; > sqlfatal();@@