Sql server 2008 将光标悬停在100k条记录上时发生超时错误

Sql server 2008 将光标悬停在100k条记录上时发生超时错误,sql-server-2008,query-performance,accounting,sqlperformance,Sql Server 2008,Query Performance,Accounting,Sqlperformance,我使用以下代码计算帐户账单,但当我的记录变为100k时,我的应用程序返回超时错误,请告诉我如何重写它以提高性能 注: 我有借贷记录,结果是余额和状态。 编辑: 我像下面那样重写了你的代码,但是,我得到了错误!递归查询“HierarchycalCTE”的“Balance”列中的锚和递归部分之间的类型不匹配。“我该怎么办?” with HierarchicalCTE (ID,Date, Debit, Credit, Balance, [Status]) As ( select ID,Dat

我使用以下代码计算帐户账单,但当我的记录变为100k时,我的应用程序返回超时错误,请告诉我如何重写它以提高性能

注: 我有借贷记录,结果是余额和状态。

编辑:

我像下面那样重写了你的代码,但是,我得到了错误!递归查询“HierarchycalCTE”的“Balance”列中的锚和递归部分之间的类型不匹配。“我该怎么办?”

with HierarchicalCTE (ID,Date, Debit, Credit, Balance, [Status]) As
(
    select ID,Date, Debit, Credit, Balance, [Status]
        from #t1 
        where ID = 1
    union all
    select tbl.ID,tbl.Date, tbl.Debit, tbl.Credit
            , Balance=(case when ((tbl.Debit > 0 and cte.[Status] = 'debtor') or (tbl.Credit > 0 and cte.[Status] = 'creditor')) then abs(cte.Balance + tbl.Debit)
                when tbl.Debit > 0 and cte.[Status] = 'creditor' then abs(cte.Balance - tbl.Debit)
                else abs(cte.Balance - tbl.Credit)
                end) 
            , cast(case when ((tbl.Debit > 0 and cte.[Status] = 'debtor') or (tbl.Debit > 0 and tbl.Debit > cte.Balance)) then 'debtor'
                else 'creditor'
                end as char(20)) as [Status]
        from #t1 tbl
            inner join HierarchicalCTE cte
            on tbl.ID = cte.ID+1 

)

select * from HierarchicalCTE

假设您的起始行有借方=200、贷方=0、余额=200、状态=借方,您希望为其余行的余额和状态输入值

基于假设使用公共表表达式(CTE)的示例,表中有一个ID列

declare @tbl table (id int, debit money, credit money, balance money, [status] varchar(20))

insert into @tbl (id, debit, credit, balance, [status])
values (1, 200, 0, 200, 'debtor')
, (2, 0, 300, 0, '')
, (3, 50, 0, 0, '')
, (4, 100, 0, 0, '')


; with cte (id, debit, credit, balance, [status])
as
(
    select id, debit, credit, balance, [status]
        from @tbl
        where id = 1
    union all
    select tbl.id, tbl.debit, tbl.credit
            , case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.credit > 0 and cte.[status] = 'creditor')) then abs(cte.balance + tbl.debit)
                when tbl.debit > 0 and cte.[status] = 'creditor' then abs(cte.balance - tbl.debit)
                else abs(cte.balance - tbl.credit)
                end as balance
            , cast(case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.debit > 0 and tbl.debit > cte.balance)) then 'debtor'
                else 'creditor'
                end as varchar(20)) as [status]
        from @tbl tbl
            inner join cte cte
            on tbl.id = cte.id + 1

)

select * from cte
初始数据

id借方贷方余额状态
1200.00 0.00 200.00债务人
2   0.00    300.00  0.00
3   50.00   0.00    0.00
4 100.00 0.00 0.00

结果

id借方贷方余额状态
1200.00 0.00 200.00债务人
2 0.00 300.00 100.00债权人
3 50.00 0.00 50.00债权人

4 100.00 0.00 50.00债务人

我想你根本不需要光标。您能提供一些数据和预期结果吗?@deterministicFail我已经在post check it out中添加了一些信息,plzCursor无法处理100K记录而不是游标使用表值函数。@Dineshalla在此之前没有使用任何表值函数帮助我处理此plzI获取此代码错误“类型在递归查询“HierarchycalCTE”的“Balance”列中的定位点和递归部分之间不匹配。”“根据错误消息,您可能需要将Balance列的定位点转换为相同的数据类型。例如,
cast(200 as money)as Balance
用于定位点。请显示您的CTE代码。cast(200 as money)不工作,仍然是相同的错误,但当把这个代码平衡=0时,它工作了,但它没有给我想要的结果!!!
declare @tbl table (id int, debit money, credit money, balance money, [status] varchar(20))

insert into @tbl (id, debit, credit, balance, [status])
values (1, 200, 0, 200, 'debtor')
, (2, 0, 300, 0, '')
, (3, 50, 0, 0, '')
, (4, 100, 0, 0, '')


; with cte (id, debit, credit, balance, [status])
as
(
    select id, debit, credit, balance, [status]
        from @tbl
        where id = 1
    union all
    select tbl.id, tbl.debit, tbl.credit
            , case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.credit > 0 and cte.[status] = 'creditor')) then abs(cte.balance + tbl.debit)
                when tbl.debit > 0 and cte.[status] = 'creditor' then abs(cte.balance - tbl.debit)
                else abs(cte.balance - tbl.credit)
                end as balance
            , cast(case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.debit > 0 and tbl.debit > cte.balance)) then 'debtor'
                else 'creditor'
                end as varchar(20)) as [status]
        from @tbl tbl
            inner join cte cte
            on tbl.id = cte.id + 1

)

select * from cte