SQL - 更有效的方式而不是使用游标

时间:2014-03-19 16:51:52

标签: sql sql-server tsql cursor

-- Declare the table we are interested in reverting.
DECLARE             @table_name                 VARCHAR(1000)
SET                 @table_name                 = 'tblCustomers'                                            -- change this

-- Declare cursor and use the select statement (the one we want to loop through).    
DECLARE             customer_cursor             CURSOR FOR
SELECT              C.CustomerId
FROM                tblCustomers                C
WHERE               ModifiedBy                  like '%crm%'
ORDER BY            C.CustomerId                DESC              

-- Open the cursor and copy the columns into the original_consumer variable.

DECLARE             @customer_id                INT

OPEN                customer_cursor
FETCH NEXT FROM     customer_cursor               
INTO                @customer_id   

-- Now loop through the old consumer id's and update their corresponding purchase and refunds records.
WHILE @@FETCH_STATUS = 0
BEGIN

    IF EXISTS ( SELECT TOP 1 UserName 
                FROM tblAudit
                WHERE TableName = @table_name
                AND TableId IN (
                                    SELECT CONVERT(VARCHAR, CustomerId) 
                                    FROM tblCustomers                                                           -- change this
                                    WHERE CustomerId = @customer_id
                                )
                AND UserName != 'crmuser'
                ORDER BY TransactionDate DESC)
    BEGIN

        UPDATE          tblCustomers
        SET             ModifiedBy                  = (SELECT TOP 1 UserName 
                                                    FROM tblAudit
                                                    WHERE TableName = @table_name
                                                    AND TableId IN (
                                                                        SELECT CONVERT(VARCHAR, CustomerId) 
                                                                        FROM tblCustomers                       -- change this
                                                                        WHERE CustomerId = @customer_id
                                                                    )
                                                    AND UserName != 'crmuser'
                                                    ORDER BY TransactionDate DESC),

                        ModifiedDate                = (SELECT TOP 1 TransactionDate 
                                                    FROM tblAudit
                                                    WHERE TableName = @table_name
                                                    AND TableId IN (
                                                                        SELECT CONVERT(VARCHAR, CustomerId) 
                                                                        FROM tblCustomers                       -- change this
                                                                        WHERE CustomerId = @customer_id
                                                                    )
                                                    AND UserName != 'crmuser'
                                                    ORDER BY TransactionDate DESC)

        WHERE           CustomerId                  = @customer_id

    END

    FETCH NEXT FROM   customer_cursor           INTO @customer_id

END

-- Finally close and deallocate the cursor to stop memory leakage.
CLOSE customer_cursor
DEALLOCATE customer_cursor

2 个答案:

答案 0 :(得分:0)

这看起来可能有效:

UPDATE tblCustomers
SET ModifiedBy = a.UserName,
    ModofiedDate = amax.LatestChangeDate
from tblCustomers t
inner join -- get the latest transaction_date for each customer
(
    select customerId, max(transaction_date) LatestChangeDate
    from tblAudit
    where TableName = @table_name
) amax on amax.customerId = t.customer_id
inner join -- get the details of changes for customer and latest date
(
    select CustomerId, UserName, transaction_date
    from tblAudit
    where table_name = @table_name
) a on a.customerId = t.customerId and a.transaction_date = amax.LatestChangeDate
WHERE t.CustomerId = @customer_id
);

(我可能有一些列名错了。)

答案 1 :(得分:0)

BEGIN TRAN

SELECT COUNT(*) 来自tblInvoices WHERE ModifiedBy =' DataImporterUser' ;与cte AS (    SELECT TableId,                   交易日期,                   用户名,                   TransactionDetail,                   ROW_NUMBER()OVER(由TableId ORDER BY TransactionDate DESC划分)ASn    来自tblAudit    表格=' tblInvoices'    AND UserName<> ' DataImporterUser' )

更新C

SET C.ModifiedBy = cte.UserName,                   C.ModifiedDate = cte.TransactionDate

FROM tblInvoices AS C

INNER JOIN cte ON cte.TableId = C.InvoiceId

在哪里rn = 1

SELECT COUNT(*) 来自tblEvents WHERE ModifiedBy =' DataImporterUser'

ROLLBACK