4.C基础_变量

变量定义

1、内存的分配

每一个变量都有一个对应的内存空间。当定义了一个int a = 0x58时,CPU为a分配了一个4字节的内存空间,并将0x58存入了该空间。

其中:4字节是由类型决定的,因为int的空间大小为4字节

2、变量的定义

同类型的变量可以一次定义一个或多个,并且也可以同时赋值,具体语法如下:

/* 定义单个变量 */
int a;
/* 定义多个无初始值的变量 */
int b,c;
/* 定义多个变量 */
int d=1,e;
/* 定义多个有初始值的变量 */
int f=1,g=1;

3、变量名注意点

  • 变量名只能以字母、数字、下划线组成
  • 变量名不能以数字开头(语法不允许)
  • 变量名不能以下划线开头(容易与编译器的变量重名、语法允许但编程规范不允许)
  • 变量名不能是关键字

<think> 我们正在讨论的是嵌入式SQL(Embedded SQL)中的FETCH语句。用户提供的代码片段是: EXEC SQL FETCH c_vten INTO :h_vten.rcp_ten_jname:h_vten.rcp_ten_jname_i, :h_vten.rcp_ten_kname:h_vten.rcp_ten_kname_i; 为了理解这段代码,我们需要从嵌入式SQL的基础开始。 ### 1. **嵌入式SQL背景** 嵌入式SQL允许在高级语言(如C、COBOL)中直接编写SQL语句,通过预处理器转换为宿主语言的可调用接口。`EXEC SQL`是嵌入式SQL的标识,后面紧跟SQL语句。 ### 2. **游标(Cursor)操作** 在嵌入式SQL中,游标用于处理多行结果集。典型操作流程为: 1. **DECLARE**:声明游标(关联SELECT语句) 2. **OPEN**:打开游标(执行SELECT) 3. **FETCH**:逐行获取结果 4. **CLOSE**:关闭游标 此处`FETCH c_vten`表示从已打开的游标`c_vten`中获取一行数据。 ### 3. **INTO子句解析** `INTO`子句指定接收查询结果的宿主变量(host variables)。特别注意: - 宿主变量前需加冒号(`:`)作为标识 - 变量顺序、类型必须与SELECT字段匹配 ### 4. **宿主变量的特殊语法** 代码中使用了带指示符变量的宿主变量: ```sql :宿主变量名:指示符变量名 ``` 这是嵌入式SQL中处理NULL值的标准方式。 ### 5. **具体变量分析** - `h_vten.rcp_ten_jname`:接收字段值的字符数组(主变量) - `h_vten.rcp_ten_jname_i`:整型指示符变量(indicator variable) ### 6. **指示符变量作用** 当数据库字段值为NULL时,指示符变量将被设置为负值(通常为-1)。若字段非NULL,则指示符变量有两种可能情况: - **0**:表示值完整存储,无截断 - **正值**:表示值被截断,数值为原始数据长度 ### 7. **代码执行流程** 1. 执行`FETCH`从游标`c_vten`获取下一行 2. 将第一列数据存入`h_vten.rcp_ten_jname` - 同时设置`h_vten.rcp_ten_jname_i`的值: - 若列为NULL → 设为-1 - 若列非NULL → - 数据完整 → 设为0 - 数据截断 → 设为原始长度 3. 同理处理第二列到`h_vten.rcp_ten_kname`及其指示符 ### 8. **关联初始化代码** 用户之前询问的初始化代码: ```c memset(h_vten.rcp_ten_jname,'\0',sizeof(h_vten.rcp_ten_jname)); h_vten.rcp_ten_jname_i = 0; ``` 其作用是确保FETCH前缓冲区干净,避免脏数据干扰。指示符归零符合"无NULL、无截断"的初始预期状态。 ### 9. **错误处理** 实际应用中,每次FETCH后应检查SQL状态(如SQLCA中的`SQLCODE`)以判断: - 是否成功获取数据(`SQLCODE=0`) - 是否到达结果集末尾(如`SQLCODE=100`) - 是否发生错误(负值错误码) > 技术细节:在Oracle Pro*C中,指示符变量类型为`short`;在DB2中为`SQLIND`(通常也定义为短整型)[^1]。 §§相关问题§§ 1. 如果指示符变量返回正值(截断),如何处理完整数据? 2. 如何在嵌入式SQL中批量获取多行数据? 3. 当FETCH返回NULL时,宿主变量数组的内容是什么? 4. 不同数据库(Oracle/DB2/SQL Server)的指示符变量处理有何差异? [^1]: 指示符变量的具体行为由SQL标准定义,各数据库实现基本一致,但错误代码可能不同。 </think> ### EXEC SQL FETCH语句解析 您提供的代码是数据库编程中的嵌入式SQL语句,用于从游标中提取数据到宿主变量。具体分析如下: ```sql EXEC SQL FETCH c_vten INTO :h_vten.rcp_ten_jname:h_vten.rcp_ten_jname_i, :h_vten.rcp_ten_kname:h_vten.rcp_ten_kname_i; ``` #### 1. **组件解析** | 组件 | 说明 | |------|------| | `EXEC SQL` | 嵌入式SQL标识符(如Pro*C, ESQL/C等) | | `FETCH c_vten` | 从名为`c_vten`的游标获取下一行数据 | | `INTO :h_vten...` | 指定接收查询结果的宿主变量 | | `:h_vten.rcp_ten_jname` | 主变量(存储字段值) | | `:h_vten.rcp_ten_jname_i` | **指示符变量**(关键组件) | #### 2. **指示符变量的作用** 这是嵌入式SQL特有的NULL值处理机制: - 当数据库字段为**NULL**时:指示符变量设为**负值**(通常为-1) - 当数据**非NULL**时: - **0**:值完整存储无截断 - **正值**:数据被截断,值=原始数据长度 #### 3. **代码执行流程 ```mermaid flowchart TD A[执行FETCH c_vten] --> B{第一列是否NULL?} B -->|是| C[设置 rcp_ten_jname_i = -1] B -->|否| D[存储值到 rcp_ten_jname] D --> E{缓冲区是否足够?} E -->|是| F[设置 rcp_ten_jname_i = 0] E -->|否| G[设置 rcp_ten_jname_i = 原始长度] A --> H{第二列处理} H --> 类似流程... ``` #### 4. **与初始化代码的关联** 您之前询问的初始化代码: ```c memset(h_vten.rcp_ten_jname,'\0',sizeof(...)); h_vten.rcp_ten_jname_i = 0; // 初始化指示符 ``` 作用是: 1. 清空字符串缓冲区(避免脏数据) 2. 设置指示符初始状态为"0"(预期无NULL/截断) 3. 为FETCH操作准备干净环境 #### 5. **实际应用场景 假设数据库表结构: ```sql CREATE TABLE vten_table ( jname VARCHAR(20), -- 日文名 kname VARCHAR(20) -- 韩文名 ); ``` 当执行FETCH时: - 若`jname`为NULL → `rcp_ten_jname_i = -1` - 若`kname='길동'`且缓冲区足够 → `rcp_ten_kname_i = 0` - 若`kname='가나다라마바사'`(长度10)但缓冲区仅8字节 → `rcp_ten_kname_i = 10` > **关键点**:指示符变量使应用程序能精确区分**空值**、**截断数据**和**完整数据**三种状态,避免将截断数据误认为完整数据[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值