如果准备好的语句需要标识符,但在您编写准备好的语句时该标识符未知,则您可构造从用户输入接收 SQL 标识符的语句。
下列 GBase 8s ESQL/C 示例提示用户输入表的名称,并在 SELECT 语句中使用该名称。由于此名称在运行时之前未知,因此该表列的数目和数据类型也未知。因此,程序不可提前分配主变量来接收每一行的数据。取而代之的是,此程序片断描述语句到一 sqlda 描述符内并以该描述符访存每一行。该访存将每一行放入程序动态地提供的内存位置内。
#include <stdio.h> EXEC SQL include sqlda; EXEC SQL include sqltypes; char *malloc( ); main() { struct sqlda *demodesc; char tablename[19]; int i; EXEC SQL BEGIN DECLARE SECTION; char demoselect[200]; EXEC SQL END DECLARE SECTION; /* 该程序选择给定的 tablename 的所有列。 交互地提供该 tablename。 */ EXEC SQL connect to 'stores_demo'; printf( "This program does a select * on a table\n" ); printf( "Enter table name: " ); scanf( "%s", tablename ); sprintf(demoselect, "select * from %s", tablename ); EXEC SQL prepare iid from :demoselect; EXEC SQL describe iid into demodesc; /* 打印描述返回的内容 */ for ( i = 0; i < demodesc->sqld; i++ ) prsqlda (demodesc->sqlvar + i);
/* 指定数据指针。 */ for ( i = 0; i < demodesc->sqld; i++ ) { switch (demodesc->sqlvar[i].sqltype & SQLTYPE) { case SQLCHAR: demodesc->sqlvar[i].sqltype = CCHARTYPE; /* 为空结束符制造空间 */ demodesc->sqlvar[i].sqllen++; demodesc->sqlvar[i].sqldata = malloc( demodesc->sqlvar[i].sqllen ); break; case SQLSMINT: /* 失败 */ case SQLINT: /* 失败 */ case SQLSERIAL: demodesc->sqlvar[i].sqltype = CINTTYPE; demodesc->sqlvar[i].sqldata = malloc( sizeof( int ) ); break; /* 对每一类型亦然。 */ } } /* 为选择声明和打开游标。 */ EXEC SQL declare d_curs cursor for iid; EXEC SQL open d_curs; /* 每次将被选择的行访存到 demodesc 内。 */ for( ; ; ) { printf( "\n" ); EXEC SQL fetch d_curs using descriptor demodesc; if ( sqlca.sqlcode != 0 ) break; for ( i = 0; i < demodesc->sqld; i++ ) { switch (demodesc->sqlvar[i].sqltype) { case CCHARTYPE: printf( "%s: \"%s\n", demodesc->sqlvar[i].sqlname, demodesc->sqlvar[i].sqldata ); break; case CINTTYPE: printf( "%s: %d\n", demodesc->sqlvar[i].sqlname, *((int *) demodesc->sqlvar[i].sqldata) ); break; /* 对每一类型亦然…… */ } } } EXEC SQL close d_curs; EXEC SQL free d_curs; /* 释放数据内存。 */ for ( i = 0; i < demodesc->sqld; i++ ) free( demodesc->sqlvar[i].sqldata ); free( demodesc ); printf ("Program Over.\n"); } prsqlda(sp) struct sqlvar_struct *sp; { printf ("type = %d\n", sp->sqltype); printf ("len = %d\n", sp->sqllen); printf ("data = %lx\n", sp->sqldata); printf ("ind = %lx\n", sp->sqlind); printf ("name = %s\n", sp->sqlname); }