在SQL中从游标创建视图?

时间:2012-03-12 00:45:27

标签: sql sql-server-2008 sql-server-2008-r2

我有一个包含此数据的表(CheckNumber):

ID  NumberFrom NumberTo StateID
1   1          10       1
2   2          3        2

这个数字代表物理文件及其状态(1个可用,2个不可用) 所以现在我想创建一个文档,想知道文档的编号和可以使用的数字。

所以我创建了这个游标。

Declare @numberUsage as table(accountID int,Number Int)
Declare @bankID int
Declare @stateID int
Declare @beginNumber int
Declare @endNumber int
Declare cCursor cursor for Select accountID, stateID, beginNumber,endNumber From Finances.CheckNumber
Open cCursor
Fetch cCursor Into @bankID,@stateID,@beginNumber,@endNumber
While @@FETCH_STATUS = 0
Begin
    Declare @actual int
    Set @actual = @beginNumber
    If @stateID = 1
    Begin
        While @actual <= @endNumber
        Begin
            if not exists(Select Number From Finances.CheckNPayment Where accountID = @bankID and Number = @actual)
            Begin
                Insert Into @numberUsage values(@bankID,@actual)
            End
            Set @actual = @actual + 1
        End
    End
    Else
    Begin
        While @actual <= @endNumber
        Begin
            Delete From @numberUsage Where accountID = @bankID And Number = @actual
            Set @actual = @actual + 1
        End
    End
    Fetch cCursor Into @bankID,@stateID,@beginNumber,@endNumber
End
Close cCursor
Deallocate cCursor
Select * From @numberUsage

结果如下:

accountID Number
1         1
1         4
1         5
1         6
1         7
1         8
1         9
1         10

是否可以将表格结果转换为视图?

1 个答案:

答案 0 :(得分:4)

这将需要几个步骤,但这是可能的。我会尝试解释每件作品:

获取序列号列表:

select row_number() over (order by name) as RN from master..spt_values

如果你需要更多,你可以交叉加入自己,你会看到更广泛的范围。现在,您可以使用它来获得可用范围。

;with Nums as (
     select row_number() over (order by name) as RN from master..spt_values)
select *
from Nums n
inner join CheckNumber cn
  on n.RN between cn.NumberFrom and cn.NumberTo

“with as()”被称为Common Table Expression (CTE)。该链接提供了有关其工作原理的更多信息。

现在我们只需要排除不可用的项目。我们可以使用相同的想法生成无法使用的数字列表,然后使用EXCEPT关键字。

;with Nums as (
     select row_number() over (order by name) as RN from master..spt_values)
select n.RN
from Nums n
inner join CheckNumber cn
  on n.RN between cn.NumberFrom and cn.NumberTo
where cn.StateId = 1
EXCEPT
select n.RN
from Nums n
inner join CheckNumber cn
  on n.RN between cn.NumberFrom and cn.NumberTo
where cn.StateId = 2

您应该能够非常轻松地将此查询适应您的实际数据结构和数据集。