FoxPro中CURSORS在SQL Server与Oracle中的等效替代方案
SQL Server与Oracle中FoxPro CURSOR的等效替代方案
FoxPro里的CURSOR是存在内存里的临时数据集,不用持久化到物理磁盘表,能存中间结果供后续查询使用。SQL Server和Oracle都有对应的等效方案,并非只能生成持久化的输出表,具体如下:
SQL Server 实现方式
1. 局部临时表(最接近FoxPro CURSOR)
以#开头,仅当前会话可见,会话结束自动销毁,完全匹配你示例中的临时数据存储需求:
-- 生成First_Name临时数据集 SELECT * INTO #First_Name FROM Customers WHERE FName = 'David'; -- 基于First_Name生成Details临时数据集 SELECT FName, LName, Contact, Email INTO #Details FROM #First_Name;
2. 表变量
以@开头,作用域更小(仅当前批处理或存储过程内有效),适合小体量数据:
-- 定义First_Name表变量(需匹配Customers的列结构) DECLARE @First_Name TABLE ( CustomerID INT, FName VARCHAR(50), LName VARCHAR(50), Contact VARCHAR(50), Email VARCHAR(100) -- 其他列按需添加 ); INSERT INTO @First_Name SELECT * FROM Customers WHERE FName = 'David'; -- 定义Details表变量 DECLARE @Details TABLE ( FName VARCHAR(50), LName VARCHAR(50), Contact VARCHAR(50), Email VARCHAR(100) ); INSERT INTO @Details SELECT FName, LName, Contact, Email FROM @First_Name;
3. CTE(公共表表达式)
适合一次性链式查询,CTE仅在当前查询语句中有效,无法跨语句复用:
WITH First_Name AS ( SELECT * FROM Customers WHERE FName = 'David' ) SELECT FName, LName, Contact, Email INTO #Details FROM First_Name;
Oracle 实现方式
1. 全局临时表
Oracle的临时表需要先定义结构,分会话级(会话结束清空)和事务级(事务提交后清空),会话级最接近FoxPro的CURSOR:
-- 创建会话级临时表First_Name(列结构匹配Customers) CREATE GLOBAL TEMPORARY TABLE First_Name ( CustomerID NUMBER, FName VARCHAR2(50), LName VARCHAR2(50), Contact VARCHAR2(50), Email VARCHAR2(100) -- 其他列按需添加 ) ON COMMIT PRESERVE ROWS; -- 填充First_Name数据 INSERT INTO First_Name SELECT * FROM Customers WHERE FName = 'David'; -- 创建会话级临时表Details CREATE GLOBAL TEMPORARY TABLE Details ( FName VARCHAR2(50), LName VARCHAR2(50), Contact VARCHAR2(50), Email VARCHAR2(100) ) ON COMMIT PRESERVE ROWS; -- 基于First_Name填充Details数据 INSERT INTO Details SELECT FName, LName, Contact, Email FROM First_Name;
2. PL/SQL集合类型(仅在PL/SQL块内使用)
如果是在PL/SQL程序中处理,可以用集合存储临时数据,完全在内存中操作:
DECLARE -- 定义匹配Customers行结构的集合类型 TYPE First_Name_Type IS TABLE OF Customers%ROWTYPE; v_First_Name First_Name_Type; -- 定义Details的行结构和集合类型 TYPE Details_Row IS RECORD ( FName Customers.FName%TYPE, LName Customers.LName%TYPE, Contact Customers.Contact%TYPE, Email Customers.Email%TYPE ); TYPE Details_Type IS TABLE OF Details_Row; v_Details Details_Type; BEGIN -- 批量获取First_Name数据 SELECT * BULK COLLECT INTO v_First_Name FROM Customers WHERE FName = 'David'; -- 基于First_Name生成Details数据 SELECT FName, LName, Contact, Email BULK COLLECT INTO v_Details FROM TABLE(v_First_Name); END; /
原FoxPro代码逻辑说明
你提供的FoxPro代码做了两件事:
- 从
Customers表筛选出FName为'David'的所有数据,存入内存临时数据集First_Name- 从
First_Name中提取指定列,存入另一个内存临时数据集Details
内容的提问来源于stack exchange,提问作者for quora
相关产品推荐
相关产品推荐

