0
点赞
收藏
分享

微信扫一扫

gbase 数据、南大通用产品文档:gbase,数据,gbase 数据,南大通用 GBase8aURI 数据类型

成义随笔 2024-11-18 阅读 15

您可以 sqlda 结构来处理参数化的 SELECT 语句。
如果准备好的 SELECT 语句有带有未知数目和数据类型的输入参数的 WHERE 子
句,则您的 GBase 8s ESQL/C 程序必须使用 sqlda 结构来定义输入参数。
要使用 sqlda 结构来为 WHERE 子句定义输入参数:
1. 声明变量来保存 sqlda 结构的地址。
2. 确定 SELECT 语句的输入参数的数目和数据类型。
3. 以诸如 malloc() 这样的系统内存分配函数分配 sqlda 结构。

以 C 语言语句指示 WHERE 子句中输入参数的数目,
其设置 sqlda 结构的 sqld 字
段。
以 C 语言语句存储每一输入参数的定义和值,其在 sqlda 结构的恰当的
sqlvar_struct 中设置 sqltype、sqllen 和 sqldata 字段:
sqltype 字段使用 sqltypes.h 头文件定义的 GBase 8s ESQL/C 数据类型常量,来表示
输入参数的数据类型。
对于 CHAR 或 VARCHAR 值,sqllen 是以字节计的字符数组的大小。对于
DATETIME 或 INTERVAL 值,此字段存储编码的限定符。
每一 sqlvar_struct 结构的 sqldata 字段包含为输入参数值分配的内存的地址。对于每
一输入参数,您可能需要使用 sqltype 和 sqllen 字段来确定需要分配的内存的数量。
如果您使用指示符变量,则还要设置 sqlind 字段,可能还要设置 sqlidata、sqlilen 和
sqlitype 字段(仅限于非 X/Open 应用程序)。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 588 -

请使用 sqlda.sqlvar 数组内的索引来标识 sqlvar_struct 结构。

以 USING DESCRIPTOR 子句,将定义了的输入参数从 sqlda 结构传至数据库服务
器。
提供输入参数的语句,依赖于该 SELECT 返回多少行。

4. 以 free() 系统调用,
释放为 sqlvar_struct 字段、
sqldata 字段,
以及为 sqlda 结构本身分配的内存。
重要: 如果 SELECT 语句在选择列表中有未知的列,则您的程序还必须以
sqlda 结构来处理这些列。

执行返回多行的参数化的 SELECT
下列描述的示例程序是 demo4.ec 示例程序的一个修改版本。它展示如何以下列条件
使用动态 SELECT 语句:
该 SELECT 返回多行。
该 SELECT 必须与游标相关联,以 OPEN 语句来执行,并以 FETCH...USING
DESCRIPTOR 语句检索它的返回值。

该 SELECT 在它的 WHERE 子句中有输入参数。
OPEN 语句包括 USING DESCRIPTOR 子句来提供 sqlda 结构中的参数值。

该 SELECT 在选择列表中有未知的列。
FETCH 语句包括 USING DESCRIPTOR 子句来存储 sqlda 结构中的返回值。
使用 sqlda 结构的样例程序
该程序说明如何使用 sqlda 结构来同时处理 WHERE 子句的数据参数和选择列表中
的列。

=================================================================
======
1. #include


2. EXEC SQL include sqlda;

3. EXEC SQL include sqltypes;

4. #define FNAME 15

5. #define LNAME 15

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 589 -

6. #define PHONE 18
=================================================================
======

2 行
该程序必须包括 GBase 8s ESQL/Csqlda.h 头文件来使用 sqlda 结构。
=================================================================
======
7. main()
8. {
9. char fname[ FNAME + 1 ];
10. char lname[ LNAME + 1 ];
11. char phone[ PHONE + 1 ];
12. int count, customer_num, i;
13. struct sqlvar_struct *pos;
14. struct sqlda *sqlda_ptr;
15. printf("Sample ESQL program running.\n\n");
16. EXEC SQL connect to 'stores7';
17. stcopy("Carole", fname);
18. stcopy("Sadler", lname);
19. EXEC SQL prepare sql_id from
20. 'select * from customer where fname=? and lname=?';
21. EXEC SQL declare slct_cursor cursor for sql_id;
=================================================================
======
9 - 14 行
9 - 11 行声明变量来保存从用户取得的数据。
sqlda_ptr 变量
(14 行)
是指向 sqlda 结
构的指针。
pos 变量
(13 行)
指向 sqlvar_struct 结构,
以便于该代码可全程处理 sqlda 的
变长部分中的每一个 sqlvar_struct 结构。不将这些变量定义作为 GBase 8s ESQL/C 主变
量。
17 - 20 行
这些行为 SELECT 语句组装字符串,
并准备该 SELECT 字符串。
此程序假设输入参
数的数目和数据类型。
因此,
在运行时刻,
无需 C 代码来确定此信息。
问号
(?)
指示 WHERE
子句中的输入参数。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 590 -

21 行
此行为准备好的语句标识符声明 slct_cursor 游标。

=================================================================
======
22. count=2;
23. whereClauseMem(&sqlda_ptr, count, fname, lname);
24. EXEC SQL open slct_cursor using descriptor sqlda_ptr;
25. free(sqlda_ptr->sqlvar);
26. free(sqlda_ptr);
=================================================================
======
22 和 23 行
这些行以输入参数信息初始化 sqlda 结构。该程序假设两个输入参数(22 行)。如
果输入参数的数目是未知的,则该程序需要解析 SELECT 字符串(不是准备好的版本),
并对它包含的 “?” 字符的数目计数。

然后,该程序调用 whereClauseMem() 函数来分配并初始化 sqlda 结构。要获取更多
信息,请参阅 69 - 77 行。
24 行
当数据库服务器执行 SELECT 时,它打开该游标。您必须包括 OPEN 的 USING
DESCRIPTOR 子句,来指定该 sqlda 结构作为输入参数值的位置。
25 和 26 行
一旦以执行了 OPEN...USING DESCRIPTOR 语句,就已使用了这些输入参数值。由
于不再需要它,因此,释放此 sqlda 结构,且它与包含该检索的值的 sqlda 不冲突。请记
住,在可使用这第二个 sqlda 之前,必须为它分配内存。
=================================================================
======
27. EXEC SQL describe sql_id into sqlda_ptr;
28. selectListMem(sqlda_ptr);
29. while(1)
30. {
31. EXEC SQL fetch slct_cursor using descriptor sqlda_ptr;
32. if(SQLCODE != 0)

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 591 -

33. {
34. printf("fetch SQLCODE %d\n", SQLCODE);
35. break;
36. }
=================================================================
======

27 行

出于演示的目的,
此程序假设在编译时刻,
选择列表列的数目和数据类型还是未知的。
它使用 DESCRIBE...INTO 语句
(27 行)
来分配 sqlda 结构,
并将关于该选择列表列的信
息放至 sqlda_ptr 指向的结构内。
28 行
selectListMem() 函数为列值处理内存的分配。

29 - 31 行
为从数据库访存的每一行执行该 while 循环。FETCH 语句(31 行)包括
USING DESCRIPTOR 子句来指定 sqlda 结构作为返回的列值的位置。

32 - 36 行
这些行检测 SQLCODE 变量的值,来确定该 FETCH 是否成功了。如果 SQLCODE
包含非零值,则该 FETCH 生成 NOT FOUND 条件(100)或错误(< 0)。在任何这些情
况下,34 行打印出 SQLCODE 值。要确定 FETCH 语句是否生成了警告,您需要检测
sqlca.sqlwarn 结构。

=================================================================
======
37. for(i=0; i

sqld; i++)

38. {

39. printf("\ni=%d\n", i);

40. prsqlda(sqlda_ptr->sqlvar[i]);

41. switch (i)

42. {

43. case 0:

44. customer_num = *(int *)(sqlda_ptr->sqlvar[i].sqldata);

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 592 -

45. break;
46. case 1:
47. stcopy(sqlda_ptr->sqlvar[i].sqldata, fname);
48. break;
49. case 2:
50. stcopy(sqlda_ptr->sqlvar[i].sqldata, lname);
51. break;
52. case 9:
53. stcopy(sqlda_ptr->sqlvar[i].sqldata, phone);
54. break;
55. }
56. }
57. printf("%d ==> |%s|, |%s|, |%s|\n",
58. customer_num, fname, lname, phone);
59. }
60. EXEC SQL close slct_cursor;
61. EXEC SQL free slct_cursor;
62. EXEC SQL free sql_id;
=================================================================
======
37 - 59 行
对于选择列表中的每一列,
这些行访问 sqlvar_struct 结构的字段。
prsqlda() 函数
(请
参阅 75 - 81 行)显示列名称(来自 sqlvar_struct.sqlname)以及它的值(来自
sqlvar_struct.sqldata field)。switch(41 - 55 行)将列值从 sqlda 结构移至恰当的长度和
数据类型的主变量内。

60 - 62 行
在访存所有行之后,
这些行释放资源。
60 行关闭 slct_cursor 游标,
且 61 行释放它。
62 行释放 sql_id 语句 ID。

=================================================================
======
63. free(sqlda_ptr->sqlvar);

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 593 -

64. free(sqlda_ptr);
65. EXEC SQL close database;
66. EXEC SQL disconnect current;
67. printf("\nProgram Over.\n");
68. }
69. whereClauseMem(descp, count, fname, lname)
70. struct sqlda **descp;
71. int count;
72. char *fname, *lname;
73. {
74. (*descp)=(struct sqlda *) malloc(sizeof(struct sqlda));
75. (*descp)->sqld=count;
76. (*descp)->sqlvar=(struct sqlvar_struct *)
77. calloc(count, sizeof(struct sqlvar_struct));
=================================================================
======

63 和 64 行
这些 free() 系统调用释放与 sqlda 结构相关联的内存。63 行释放分配
给 sqlvar_struct 结构的内存。64 行释放为 sqlda 结构分配的内存。该程序
不需要释放与 sqldata 字段相关联的内存,
因为这些字段已经使用了在数据缓
冲区中的空间。

69 - 77 行
whereClauseMem() 函数以输入参数定义来初始化 sqlda 结构。74 行为 sqlda 结构
分配内存来保存 WHERE 子句中的输入参数。使用 DESCRIBE...INTO 来分配 sqlda 导
致保存关于该 SELECT 的选择列表列的信息的 sqlda。由于您想要在 WHERE 子句中描
述输入参数,因此,请不要在此使用 DESCRIBE。

75 行将 sqlda 结构的 sqld 字段设置为 count 的值(2),来指示 WHERE 子句中
参数的数目。76 和 77 行使用 calloc() 系统函数来分配内存,以便于 WHERE 子句中的
每一输入参数都有一个 sqlvar_struct 结构。
然后,
这些行设置 sqlda 结构的 sqlvar 字段,
以便于它指向此 sqlvar_struct 内存。

=================================================================

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 594 -

======
78. (*descp)->sqlvar[0].sqltype = CCHARTYPE;
79. (*descp)->sqlvar[0].sqllen = FNAME + 1;
80. (*descp)->sqlvar[0].sqldata = fname;
81. (*descp)->sqlvar[1].sqltype = CCHARTYPE;
82. (*descp)->sqlvar[1].sqllen = LNAME + 1;
83. (*descp)->sqlvar[1].sqldata = lname;
84. }
85. selectListMem(descp)
86. struct sqlda *descp;
87. {
88. struct sqlvar_struct *col_ptr;
89. static char buf[1024];
90. int pos, cnt, size;
91. printf("\nWITHIN selectListMem: \n");
92. printf("number of parms: %d\n", descp->sqld);
93. for(col_ptr=descp->sqlvar, cnt=pos=0; cnt < descp->sqld;
94. cnt++, col_ptr++)
95. {
96. prsqlda(col_ptr);
97. pos = rtypalign(pos, col_ptr->sqltype);
98. col_ptr->sqldata = &buf[pos];
99. size = rtypmsize(col_ptr->sqltype, col_ptr->sqllen);
100. pos += size;
101. }
102. }
=================================================================
======

78 - 84 行
78 - 80 行设置 sqlvar_struct 结构的 sqltype、sqllen 和 sqldata 字段,来描述第一
个输入参数:其数据存储在 fname 缓冲区中的长度为 16(FNAME + 1)的字符
(CCHARTYPE)
主变量。
fname 缓冲区是在 main() 程序中声明的字符缓冲区,
且作为参
数传给 whereClauseMem()。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 595 -

81 行设置 sqlvar_struct 结构的 sqltype、sqllen 和 sqldata 字段来描述第二个输入
参数。此参数是针对 lname 列的。定义它的方式,与 fname 列一样(78 - 80 行),但它
从 lname 缓冲区接收它的数据 [还被从 main() 传至 whereClauseMem()]。

85 - 102 行
selectListMem() 函数分配内存,并为参数化的 SELECT 语句的未知的选
择列表列初始化 sqlda 结构。
执行参数化的单个 SELECT 语句
在前一主题中的说明假设参数化的 SELECT 语句返回多个值,
因此,
与游标相关联。
如果您在此时知道您编写一个程序,
参数化的 SELECT 语句总是只返回一行,
则您可省略
游标并使用 EXECUTE...USING DESCRIPTOR...INTO 语句,而不使用 OPEN...USING
DESCRIPTOR 语句,来指定来自 sqlda 结构的参数值。

举报

相关推荐

0 条评论