由于 SQL 预处理器不能识别指针或引用表达式,因此主机变量必须使用简单名称。例如,以下语句不能正常工作,因为 SQL 预处理器不能理解点运算符。同样的语法在 SQL 中具有不同的含义。
// Incorrect statement: EXEC SQL SELECT LAST sales_id INTO :mystruct.mymember; |
虽然不允许使用以上语法,但仍然可以通过以下方法来使用表达式:
用 #if 0 预处理器指令括起 SQL 声明部分。因为 SQL 预处理器忽略这些预处理器指令,所以它将读取该声明并将它们用于模块的其余部分。
定义与主机变量同名的宏。由于 #if 指令的存在,C 编译器将看不到 SQL 的声明部分,所以不会出现冲突。必须确保将宏解释为相同类型的主机变量。
以下代码演示了此方法,使 SQL 预处理器看不到 host_value 表达式。
#include <sqlerr.h> #include <stdio.h> EXEC SQL INCLUDE SQLCA; typedef struct my_struct { long host_field; } my_struct; #if 0 // Because it ignores #if preprocessing directives, // SQLPP reads the following declaration. EXEC SQL BEGIN DECLARE SECTION; long host_value; EXEC SQL END DECLARE SECTION; #endif // Make C/C++ recognize the 'host_value' identifier // as a macro that expands to a struct field. #define host_value my_s.host_field |
因为 SQLPP 处理器忽略条件编译的指令,所以 host_value 被视为 long 类型的主机变量,随后,在将该名称用作主机变量时将其发出。C/C++ 编译器处理发出的文件,并将用 my_s.host_field 替换所有如此使用的该名称。
准备好以上声明后,就可继续按以下方法访问 host_field 了。
void main( void ) { my_struct my_s; db_init( &sqlca ); EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL"; EXEC SQL DECLARE my_table_cursor CURSOR FOR SELECT int_col FROM my_table order by int_col; EXEC SQL OPEN my_table_cursor; for( ; ; ) { // :host_value references my_s.host_field EXEC SQL FETCH NEXT AllRows INTO :host_value; if( SQLCODE == SQLE_NOTFOUND ) { break; } printf( "%ld\n", my_s.host_field ); } EXEC SQL CLOSE my_table_cursor; EXEC SQL DISCONNECT; db_fini( &sqlca ); } |
可以使用相同方法将其它左值用作主机变量:
间接指针
*ptr p_struct->ptr (*pp_struct)->ptr |
数组引用
my_array[ I ] |
任意复杂的左值
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |