此部分描述如何使用系统描述符区域来处理 SELECT 语句。 要使用系统描述符区域来处理未知的选择列表列: 1. 以 PREPARE 语句准备 SELECT 语句,来给它一个语句标识符。该 SELECT 语句不可包括 INTO TEMP 子句。 2. 以 ALLOCATE DESCRIPTOR 语句分配系统描述符区域。 3. 以 DESCRIBE...USING SQL DESCRIPTOR 语句确定该选择列表列的数 目和数据类型。DESCRIBE 为该选择列表中的每一列填充项描述符。 以 GET DESCRIPTOR 语句保存主变量中的选择列表列的数目,来获取 COUNT 字 段的值。 4. 声明并打开一游标,然后使用 FETCH...USING SQL DESCRIPTOR 语 句来将列值访存至分配了的系统描述符区域内,一次访存一行。 5. 以 GET DESCRIPTOR 语句将行数据从系统描述符区域检索至主变量, 来访问 DATA 字段。 6. 以 DEALLOCATE DESCRIPTOR 语句释放系统描述符区域。 重要: 如果 SELECT 语句在 WHERE 子句中有未知的输入参数,则您的程序还必 须以系统描述符区域来处理这些输入参数。 执行返回多行的 SELECT demo4.ec 样例程序展示如何以下列条件执行动态 SELECT 语句: SELECT 返回多行。 必须将 SELECT 与游标相关联,以 OPEN 语句执行,并以 FETCH...USING SQL DESCRIPTOR 语句检索它的返回值。 GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 519 - SELECT 或没有输入参数,或没有 WHERE 子句。 OPEN 语句不需要包括 USING 子句。 SELECT 在它的选择列表中有未知的列。 FETCH 语句包括 USING SQL DESCRIPTOR 子句来在 sqlda 结构中存储返回值。 demo4.ec 样例程序 此 demo4 程序是 demo3 样例程序的一个版本(demo3.ec 样例程序),该程序 使用系统描述符区域来保存选择列表列。demo4 程序不包括异常处理。 ================================================================= ====== 1. #include 2. EXEC SQL define NAME_LEN 15; 3. main() 4. { 5. EXEC SQL BEGIN DECLARE SECTION; 6. mint i; 7. mint desc_count; 8. char demoquery[80]; 9. char colname[19]; 10. char result[ NAME_LEN + 1 ]; 11. EXEC SQL END DECLARE SECTION; ===================================================================== == 5 - 11 行 这些行声明主变量来保存从用户获得的数据,以及从系统描述符区域检索的列值。 ================================================================= ====== GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 520 - 12. printf("DEMO4 Sample ESQL program running.\n\n"); 13. EXEC SQL connect to 'stores7'; 14. /* These next three lines have hard-wired both the query and 15. * the value for the parameter. This information could have been 16. * been entered from the terminal and placed into the strings 17. * demoquery and the query value string (queryvalue), * respectively. 18. */ 19. sprintf(demoquery, "%s %s", 20. "select fname, lname from customer", 21. "where lname < 'C' "); 22. EXEC SQL prepare demo4id from :demoquery; 23. EXEC SQL declare demo4cursor cursor for demo4id; 24. EXEC SQL allocate descriptor 'demo4desc' with max 4; 25. EXEC SQL open demo4cursor; ===================================================================== == 14 - 22 行 这些行为(demoquery 中的)语句组装字符串,并准备它作为 demo4id 语句标 识符。 23 行 这一行为准备好的语句标识符 demo4id 声明 demo4cursor 游标。所有非单个的 SELECT 语句都必须有一个声明了的游标。 24 行 要能够为选择列表列使用系统描述符区域,您必须首先分配它。此 ALLOCATE DESCRIPTOR 语句分配带有四个项描述符的 demo4desc 系统描述符区域。 GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 521 - 25 行 数据库服务器执行 SELECT 语句,当它打开 demo4cursor 游标时。如果您 的 SELECT 语句的 WHERE 子句包含输入参数,则您还需要指定 OPEN 语句的 USING SQL DESCRIPTOR 子句。 ================================================================= ====== 26. EXEC SQL describe demo4id using sql descriptor 'demo4desc'; 27. EXEC SQL get descriptor 'demo4desc' :desc_count = COUNT; 28. printf("There are %d returned columns:\n", desc_count); 29. /* Print out what DESCRIBE returns */ 30. for (i = 1; i <= desc_count; i++) 31. prsysdesc(i); 32. printf("\n\n"); ===================================================================== == 26 行 DESCRIBE 语句描述 demo4id 语句标识符中准备好的语句的选择列表列。为此, DESCRIBE 必须跟在 PREPARE 之后。此 DESCRIBE 包括 USING SQL DESCRIPTOR 子句来指定 demo4desc 系统描述符区域作为这些列描述的位置。 27 和 28 行 27 行使用 GET DESCRIPTOR 语句来获得由 DESCRIBE 发现的选择列表列的数目。 从 demo4desc 系统描述符区域的 COUNT 字段读取此数目,并保存在 desc_count 主变 量中。28 行将此信息显示给用户。 GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 522 - 29 - 31 行 此 for 循环仔细检查选择列表的列的项描述符。它使用 desc_count 主变量来确定由 DESCRIBE 语句初始化的项描述符的数目。对于每一项描述符,for 循环调用 prsysdesc() 函数(31 行)来保存诸如主变量中列的数据类型、长度和名称之类的信息。 ================================================================= ====== 33. for (;;) 34. { 35. EXEC SQL fetch demo4cursor using sql descriptor 'demo4desc'; 36. if (strncmp(SQLSTATE, "00", 2) != 0) 37. break; 38. /* Print out the returned values */ 39. for (i = 1; i <= desc_count; i++) 40. { 41. EXEC SQL get descriptor 'demo4desc' VALUE :i 42. :colname=NAME, :result = DATA; 43. printf("Column: %s\tValue:%s\n ", colname, result); 44. } 45. printf("\n"); 46. } ===================================================================== == 33 - 46 行 对于从数据库访存的每一行,执行此内部 for 循环。FETCH 语句(35 行)包括 USING SQL DESCRIPTOR 子句来指定 demo4desc 系统描述符区域为列值的位置。在此 FETCH 执行之后,将列值存储在指定的系统描述符区域中。 if 语句(36 和 37 行)检测 SQLSTATE 变量的值来确定该 FETCH 是否成功了。 如果 SQLSTATE 包含不同于 "00" 的类代码, 则 FETCH 生成警告 ("01") 、 NOT FOUND 条件("02")或错误(> "02")。在任何这些情况下,37 行结束该 for 循环。 GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 523 - 对于选择列表中每一列, 39 - 45 行访问项描述符的字段。 在每一 FETCH 语句之后, GET DESCRIPTOR 语句(41 和 42 行)将 DATA 字段的内容加载至恰当类型和长度的 主变量内。第二个 for 循环(39 - 44 行)确保为选择列表中的每一列调用 GET DESCRIPTOR。 重要: 在此 GET DESCRIPTOR 语句中,demo4 程序假设返回的列为 CHAR 数据 类型。如果该程序未做此假设,则它会需要检查 TYPE 和 LENGTH 字段来确定要保存该 DATA 值的主变量的恰当的数据类型。 ================================================================= ====== 47. if(strncmp(SQLSTATE, "02", 2) != 0) 48. printf("SQLSTATE after fetch is %s\n", SQLSTATE); 49. EXEC SQL close demo4cursor; 50. /* free resources for prepared statement and cursor*/ 51. EXEC SQL free demo4id; 52. EXEC SQL free demo4cursor; 53. /* free system-descriptor area */ 54. EXEC SQL deallocate descriptor 'demo4desc'; 55. EXEC SQL disconnect current; 56. printf("\nDEMO4 Sample Program Over.\n\n"); 57. } ===================================================================== == 47 和 48 行 在该 for 循环之外, 程序再次检测 SQLSTATE 变量, 以便于它可通知用户执行成功、 运行时刻错误,或警告(类代码不等于 "02")。 49 行 GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 524 - 在访存所有行之后,CLOSE 语句关闭 demo4cursor 游标。 50 - 54 行 这些 FREE 语句释放为准备好的语句(51 行)和数据库游标(52 行)分配的资源。 DEALLOCATE DESCRIPTOR 语句(54 行)释放分配给 demo4desc 系统描述符区 域的内存。 ================================================================= ====== 58. prsysdesc(index) 59. EXEC SQL BEGIN DECLARE SECTION; 60. PARAMETER mint index; 61. EXEC SQL END DECLARE SECTION; 62. { 63. EXEC SQL BEGIN DECLARE SECTION; 64. mint type; 65. mint len; 66. mint nullable; 67. char name[40]; 68. EXEC SQL END DECLARE SECTION; 69. EXEC SQL get descriptor 'demo4desc' VALUE :index 70. :type = TYPE, 71. :len = LENGTH, 72. :nullable = NULLABLE, 73. :name = NAME; 74. printf(" Column %d: type = %d, len = %d, nullable=%d, name = %s\n", 75. index, type, len, nullable, name); 76. } GBase 8s ESQL/C 编程指南 南大通用数据技术股份有限公司 - 525 - ===================================================================== == 58 - 76 行 prsysdesc() 函数显示关于选择列表列的信息。 它使用 GET DESCRIPTOR 语句来访问 来自 demo4desc 系统描述符区域的一个项描述符。 GET DESCRIPTOR 语句 (70 - 74 行) 访问来自 demo4desc 中的项描述符的 TYPE、 LENGTH、 NULLABLE 和 NAME 字段,来提供关于一列的信息。 它将此信息存储在恰当 长度和数据类型的主变量中。VALUE 关键字指示要访问的项描述符的数目。 执行单个 SELECT demo4 程序假设该 SELECT 语句返回多行,因此,该程序将该语句与游标相关联。 如果您此刻知道,您编写的程序的动态 SELECT 总是只返回一行,则可省略该游标,并使 用 EXECUTE...INTO SQL DESCRIPTOR 语句,而不用 FETCH...USING SQL DESCRIPTOR。您需要使用 DESCRIBE 语句来定义选择列表列。