I have a table (CheckNumber) with this data:
ID NumberFrom NumberTo StateID
1 1 10 1
2 2 3 2
This numbers represents physical documents and its states (1 is usable and 2 is unusuable) So now I want to create a document and want to know what number the document will have and what nummbers can be used.
So I have created this cursor.
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
The result is this:
accountID Number
1 1
1 4
1 5
1 6
1 7
1 8
1 9
1 10
Is it possible to convert the table result to a view?
This will take a few steps, but it's possible. I'll try to explain each piece:
Get a list of sequential numbers:
select row_number() over (order by name) as RN from master..spt_values
If you need more than that, you can cross join to itself and you'll see a lot wider range. Now, you can use this to get your usable range.
;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
The "with as ()" is called a Common Table Expression (CTE). The link has more info on how it works.
Now we just need to exclude the unusable items. We can use the same idea to generate a list of unusable numbers and then use the EXCEPT keyword.
;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
You should be able to adapt this query to your actual data structure and data set fairly easily.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With