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

SQL Anywhere 11.0.1 (中文) » UltraLite - C 及 C++ 编程 » 应用程序开发 » 使用嵌入式 SQL 开发应用程序 » 使用主机变量

 

主机变量的作用域

主机变量的声明部分可出现在通常可以声明 C 变量的任何地方,包括 C 函数的参数声明部分。C 语言变量有其常规作用域(在定义它们的块中可用)。但是,因为 SQL 预处理器不扫描 C 代码,所以它与 C 语言块无关。

预处理器假定所有的主机变量都是全局的

就 SQL 预处理器而言,主机变量在其声明之后的源模块中都是全局已知的。主机变量不得同名。此规则的唯一例外情况是当两个主机变量类型(包括任何必需的长度)相同时,它们可以同名。

最好是每个主机变量都具有唯一名称。

示例

因为 SQL 预处理器不能分析 C 代码,因此它假定所有主机变量(不管它们是在哪里声明的)在其声明之后都是全局已知的。

// Example demonstrating poor coding
EXEC SQL BEGIN DECLARE SECTION;
   long emp_id;
EXEC SQL END DECLARE SECTION;
long getManagerID( void )
{
   EXEC SQL BEGIN DECLARE SECTION;
      long manager_id = 0;
   EXEC SQL END DECLARE SECTION;
   EXEC SQL SELECT manager_id
            INTO :manager_id
            FROM employee
            WHERE emp_number = :emp_id;
   return( manager_number );
}
void setManagerID( long manager_id )
{
   EXEC SQL UPDATE employee
            SET manager_number = :manager_id
            WHERE emp_number = :emp_id;
}

虽然以上代码可以使用,但它却容易造成混淆,因为 SQL 预处理器在处理 setManagerID 中的语句时,要依赖于 getManagerID 内部的声明。此段代码应按如下所示重写:

// Rewritten example
#if 0
   // Declarations for the SQL preprocessor
   EXEC SQL BEGIN DECLARE SECTION;
      long emp_id;
      long manager_id;
   EXEC SQL END DECLARE SECTION;
#endif
long getManagerID( long emp_id )
{
   long manager_id = 0;
   EXEC SQL SELECT manager_id
            INTO :manager_id
            FROM employee
            WHERE emp_number = :emp_id;
   return( manager_number );
}
void setManagerID( long emp_id, long manager_id )
{
   EXEC SQL UPDATE employee
            SET manager_number = :manager_id
            WHERE emp_number = :emp_id;
}

SQL 预处理器会看到在 #if 指令中包含的主机变量声明,因为它将忽略这些指令。另一方面,它忽略过程中的声明,因为它们不在 DECLARE SECTION 内部。相反,C 编译器会忽略 #if 指令内部的声明,并使用过程内部的声明。

这些声明能够正常工作,仅仅是因为将同名的变量声明为完全相同的类型。