Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » UltraLite - C 及 C++ 编程 » 应用程序开发 » 使用嵌入式 SQL 开发 UltraLite C++ 应用程序 » 主机变量

 

作为主机变量的表达式

由于 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 ]
  • 任意复杂的左值