首页 > 解决方案 > SQL Server 中的光标用法

问题描述

这是我的代码;

创建表拆分器
(
     标识 INT
    ,Vals VARCHAR(10)
)

插入分离器值
(1,'A,B,C'),
(2,'D,E,F')

声明 @Id INT
声明 @Str VARCHAR(10)
DECLARE @Tbl TABLE(Id int, Vals varchar(10))

声明 MyCursor CURSOR FOR

    从拆分器中选择 Id、Vals

打开我的光标  

从 MyCursor 获取下一个到 @Id、@Str

而@@FETCH_STATUS = 0  
开始  

     插入@Tbl
     选择@Id, substring(@Str,charindex(',',@Str)-1,1)
     设置@Str=substring(@Str,charindex(',',@Str)+1,len(@Str))

从 MyCursor 获取下一个到 @Id,@Str

结尾

关闭我的光标  
DEALLOCATE MyCursor

我想逐行列出值,如下所示;

1-A
1-A
1-A
2-D
2-E
2-F

我的代码有什么问题?我只是想知道光标是如何工作的..提前谢谢..

标签: sqlsql-serverdatabase-cursor

解决方案


您的问题以正确的示例数据和代码开始,但以“我的代码有什么问题?”结束。- 您当前的代码返回:

1    a
2    d

这是因为您@str在循环内设置变量,然后用光标覆盖它。

string_split如果您使用的是 2016 或更高版本,并且在该版本之前由 Adam Machanic 的 CLR 函数,则应使用内置在 SQL Server 中拆分字符串。如果您正在使用低于 2016 的版本并且由于某种原因无法使用 CLR,您可能应该使用 XML 拆分器,如 Aaron Bertrand 的Split strings the right way – or the next best way或 Jeff Moden 的DelimitedSplit8K中所示。

在 SQL 中,游标通常是做任何事情的错误工具。SQL 最适用于基于集合的方法,而不是 RBAR 方法(游标可以做的所有事情)。

基本上,游标只是获取它的选择语句的结果集并将其吐出 Row By Agonizing Row with 与fetch next
在基于集合的方法中完成的相同操作相比,这通常意味着糟糕的性能。
这并不意味着你永远不应该使用游标,但这是我所说的最后手段,只有当你绝对别无选择时。


推荐阅读