当前位置: 代码迷 >> Sql Server >> [原] 游标替代解决办法
  详细解决方案

[原] 游标替代解决办法

热度:392   发布时间:2016-04-27 19:11:00.0
[原] 游标替代
我一直反对使用游标,游标在SQL定义成面向过程,这与SQL的面向集合感觉有点不符。而且,游标会引起很多性能,资源问题。我前几天查了一下我们的数据库服务器。一共搜出将近一百个用了游标存储过程,更要命的是:游标竟然没有 Close,也没有 DEALLOCATE。俺头大了,俺这个非专职的临时DBA也管不了这么多,全找出来,让他们自行改吧。
俺这临时DBA没有权力,但有些东东,还得龟腚一下。以后严禁使用游标。不让用,得有个替代的办法吧。这个方法别人用了N年,俺也用了N年,CSDN的贴子里也贴了N年,俺再多贴一次,也未不可。

-----------------------
-- 查找未关闭的游标。
-----------------------
CREATE TABLE ##游标 ( Var_DBName VarChar(255),Var_ProcName VarChar(255) );
DECLARE @Var_DbNaem VarChar(255);
DECLARE @NVr_Cmd NVarChar(4000);

SELECT @Var_DbNaem=MIN([NAME]) from master..sysdatabases

WHILE NOT @Var_DbNaem IS NULL BEGIN
SET @NVr_Cmd='
INSERT INTO ##游标(Var_ProcName,Var_DBName)
SELECT distinct 名称,''' [email protected]_DbNaem + '''
FROM (
select 
b.Name as 名称
,a.Name as 参数
,c.Text as 语句
from 
[' [email protected]_DbNaem + '].DBO.syscolumns a
left join
[' [email protected]_DbNaem + '].DBO.sysobjects b on a.ID=b.ID
join
[' [email protected]_DbNaem + '].DBO.syscomments c on c.ID=b.ID
where
b.xtype in(''FN'',''IF'',''TF'',''P'') AND C.TEXT LIKE ''%CURSOR%'' AND (NOT C.TEXT LIKE ''%DEALLOCATE%'')
) AS T'

PRINT @NVR_CMD

EXECUTE(@NVR_CMD);
SELECT @Var_DbNaem=MIN([NAME]) from master..sysdatabases WHERE [NAME]>@Var_DbNaem
END

SELECT * FROM ##游标
DROP TABLE ##游标

GO

SQL code
USE TESTGOCREATE TABLE LX1(INT_I INT,VAR_A VARCHAR(32),VAR_B VARCHAR(32))GOINSERT INTO LX1 VALUES(1,'A','E')INSERT INTO LX1 VALUES(2,'B','F')INSERT INTO LX1 VALUES(3,'C','G')INSERT INTO LX1 VALUES(4,'D','H')GO-----------------------------原表能确定唯一的单一主键。--如果是多主键,可以在表变量中添加自增字段(IDENTITY)或字符型的组合字段( KEY1 + '|' + KEY2 + '| + KEY3 ... ) 。---------------------------DECLARE @INT_I INTDECLARE @VAR_A VARCHAR(32)DECLARE @VAR_B VARCHAR(32)DECLARE @TAB_LX TABLE (INT_I INT,VAR_A VARCHAR(32),VAR_B VARCHAR(32))INSERT INTO @TAB_LX SELECT * FROM LX1SELECT @INT_I=MIN(INT_I) FROM @TAB_LXWHILE NOT @INT_I IS NULL BEGIN    SELECT @VAR_A=VAR_A,@VAR_B=VAR_B FROM @TAB_LX WHERE [email protected]_I        --提取值    PRINT @VAR_A + '   '  + @VAR_B        SELECT @INT_I=MIN(INT_I) FROM LX1 WHERE INT_I>@INT_IENDGO-----------------------------原表没有唯一主键--可在表变量中添加一个自增编号。---------------------------DECLARE @INT_ID INTDECLARE @VAR_A VARCHAR(32)DECLARE @VAR_B VARCHAR(32)DECLARE @TAB_LX TABLE (INT_ID INT IDENTITY(1,1) ,INT_I INT,VAR_A VARCHAR(32),VAR_B VARCHAR(32))INSERT INTO @TAB_LX (INT_I,VAR_A,VAR_B) SELECT * FROM LX1SELECT @INT_ID=MIN(INT_ID) FROM @TAB_LXWHILE NOT @INT_ID IS NULL BEGIN    SELECT @VAR_A=VAR_A,@VAR_B=VAR_B FROM @TAB_LX WHERE [email protected]_ID        ---提取值。    PRINT @VAR_A + '   '  + @VAR_B        SELECT @INT_ID=MIN(INT_ID) FROM @TAB_LX WHERE INT_ID>@INT_IDENDGO


------解决方案--------------------
学习!
------解决方案--------------------
探讨
学习!

------解决方案--------------------
mark,
也不能一概而轮,毕竟cursor还是有其存在的必要性的,
有些时候cursor还是很好用的。。。。。。
------解决方案--------------------
不错
------解决方案--------------------
游标会引起很多性能
------解决方案--------------------
探讨
mark,
也不能一概而轮,毕竟cursor还是有其存在的必要性的,
有些时候cursor还是很好用的。。。。。。

------解决方案--------------------
关于游标csdn这好像讨论过,不过想用好它,肯定要先了解它的用法和原理!
------解决方案--------------------
  相关解决方案