游标的经典示例
|
--create table Temp
--(
--ID int,
--Name nvarchar(50),
--MinValue int,
--MaxValue int,
--TableName nvarchar(50),
--Field nvarchar(50)
--)
--insert Temp values(1,'A10',10,20,'T1','F10')
--insert Temp values(2,'A11',15,29,'T1','F11')
--insert Temp values(3,'B20',35,58,'T2','F20')
--insert Temp values(4,'B21',25,38,'T2','F21')
--insert Temp values(5,'C31',36,48,'T3','F30')
select * from temp
--create table T1
--(
--ID int,
--F10 nvarchar(50),
--F11 nvarchar(50)
--)
--insert T1 values(1,'11','28')
--insert T1 values(2,'12','27')
select * from T1
--create table T2
--(
--ID int,
--F20 nvarchar(50),
--F21 nvarchar(50)
--)
--insert T2 values(1,'36','37')
--insert T2 values(2,'57','26')
select * from T2
--create table T3
--(
--ID int,
--F30 nvarchar(50),
--F31 nvarchar(50)
--)
--insert T3 values(1,'49','58')
--insert T3 values(2,'52','42')
select * from T3
解决方案:
declare @table table
(
id varchar(20),
name varchar(20),
minvalue int,
maxvalue int,
value int
)
declare @id varchar(20)
declare @name varchar(20)
declare @minvalue int
declare @maxvalue int
declare @fieldName nvarchar(50)
declare @tableName nvarchar(50)
declare @sql nvarchar(200)
declare @ret nvarchar(200)
DECLARE myCursor CURSOR FOR
select * from temp
OPEN myCursor
FETCH NEXT FROM myCursor
---------------------插入第一条结果Begin--------------------------
INTO @id,@name, @minvalue,@maxvalue,@tableName,@fieldName
set @sql = N'select top 1 @ret=['+@fieldName+'] from ['+@tableName+'] order by ['+@fieldName+'] desc'
execute sp_executesql @sql,N'@ret nvarchar(200) out',@ret out
insert into @table select @id,@name,@minvalue,@maxvalue,@ret
---------------------插入第一条结果 End--------------------------
--------------如果FETCH成功,则继续执行插入操作 Begin--------------
WHILE @@FETCH_STATUS = 0 --如果FETCH成功,则继续执行插入操作
BEGIN
FETCH NEXT FROM myCursor
INTO @id,@name, @minvalue,@maxvalue,@tableName,@fieldName
set @sql = N'select top 1 @ret=['+@fieldName+'] from ['+@tableName+'] order by ['+@fieldName+'] desc'
execute sp_executesql @sql,N'@ret nvarchar(200) out',@ret out
insert into @table select @id,@name,@minvalue,@maxvalue,@ret
END
--------------如果FETCH成功,则继续执行插入操作 End--------------
CLOSE myCursor
DEALLOCATE myCursor
select * from @table
解决方案II
--首先再建一个表
--通过动态游标实现
CREATE PROCEDURE [dbo].[StoredProcedure6]
AS
BEGIN
DECLARE MyCURSOR CURSOR FOR --声明一个游标
--SELECT [Name], TypeName, [Min], [Max],TableName,Field FROM [Temp]
SELECT ID, TableName,Field FROM [Temp]
open MyCURSOR --打开游标
declare @ID int
declare @TableName nvarchar(50)
declare @Field nvarchar(50)
declare @Namet nvarchar(50)
declare @TypeNamet nvarchar(50)
declare @Mint nvarchar(50)
declare @Maxt nvarchar(50)
declare @i int
declare @w int
declare @s nvarchar(1000)
declare @sql nvarchar(1000)
declare @f nvarchar(50)
fetch next from MyCURSOR into @ID ,@TableName,@Field
while(@@fetch_status=0)
begin
declare @username nvarchar(50)
set @sql='declare classcursor_2 cursor for '+' SELECT '+@Field+' FROM '+ @TableName
exec (@sql)
open classcursor_2
fetch next from classcursor_2 into @username
while (@@fetch_status=0)
begin
select @Namet=[Name],@TypeNamet=TypeName, @Mint=[Min], @Maxt=[Max] from [Temp] where ID=@ID
INSERT INTO TempBiao([Name], TypeName, [Min], [Max], Field)
VALUES (@Namet, @TypeNamet, @Mint, @Maxt,@username)
fetch next from classcursor_2 into @username
end
close classcursor_2
deallocate classcursor_2
fetch next from MyCURSOR into @ID,@TableName,@Field
end
close MyCURSOR
deallocate MyCURSOR
END
@@FETCH_STATUS
返回针对连接当前打开的任何游标发出的上一条游标 FETCH 语句的状态。
返回值 | 说明 |
0 | FETCH 语句成功。 |
-1 | FETCH 语句失败或行不在结果集中。 |
-2 | 提取的行不存在。 |
备注
由于 @@FETCH_STATUS 对于在一个连接上的所有游标都是全局性的,所以要谨慎使用 @@FETCH_STATUS。在执行一条 FETCH 语句后,必须在对另一游标执行另一 FETCH 语句前测试 @@FETCH_STATUS。在此连接上出现任何提取操作之前,@@FETCH_STATUS 的值没有定义。
例如,用户从一个游标执行一条 FETCH 语句,然后调用一个存储过程,此存储过程打开并处理另一个游标的结果。从被调用的存储过程返回控制后,@@FETCH_STATUS 反映的是在存储过程中执行的最后的 FETCH 语句的结果,而不是在存储过程被调用之前的 FETCH 语句的结果。
若要检索特定游标的最后提取状态,请查询 sys.dm_exec_cursors 动态管理函数的 fetch_status 列。
示例
以下示例用 @@FETCH_STATUS 控制一个 WHILE 循环中的游标活动。
DECLARE Employee_Cursor CURSOR FOR
SELECT EmployeeID, Title FROM AdventureWorks.HumanResources.Employee;
OPEN Employee_Cursor;
FETCH NEXT FROM Employee_Cursor;
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM Employee_Cursor;
END;
CLOSE Employee_Cursor;
DEALLOCATE Employee_Cursor;
GO