重置临时表的标识

时间:2014-06-10 12:53:13

标签: sql sql-server stored-procedures

我目前正在开发一个SP,它会为系统返回一个客户列表。 SP根据分页返回大量数据。但是,我注意到由于删除了重复记录,要返回的正确数据量不正确。我需要能够重新设置包含此数据的临时表。我尝试过以下操作但没有用。

DBCC CHECKIDENT (#ReturnData, RESEED, 0)

这是SP。

USE [SupplyCatalogDB]
GO
/****** Object:  StoredProcedure [dbo].[CustomerLoadAllPaged]    Script Date: 6/10/2014 8:33:16 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CustomerLoadAllPaged]
(
    @CustomerRoles nvarchar(20) = NULL,
    @IsActive bit = NULL,
    @Username nvarchar(1000) = NULL,
    @FirstName nvarchar(MAX) = NULL,
    @LastName nvarchar(MAX) = NULL,
    @UnitId int = NULL,
    @SortBy int = 0, --0 = CreatedOnUtc Asc, 1 = CreatedOnUtc Desc, 2 = Username Asc, 3 = Username Desc,
    --4 = CustomerName Asc, 5 = CustomerName Desc, 6 = Unit Asc, 7 = Unit Desc, 8 = CustomerRoles Asc,
    --9 = CustomerRoles Desc, 10 = Active Asc, 11 = Active Desc, 12 = LastActivityOnUtc Asc,
    --13 = LastActivityOnUtc Desc, 14 = Location Asc, 15 = Location Desc, 16 = TM Asc, 17 = TM Desc,
    --18 = Phone Asc, 19 = Phone Desc
    @PageIndex int = 0, 
    @PageSize int = 2147483644,
    @TotalRecords int = null OUTPUT
)
AS
BEGIN
    DECLARE @SQL nvarchar(MAX)
--paging
DECLARE @PageLowerBound int
DECLARE @PageUpperBound int
DECLARE @RowsToReturn int
SET @RowsToReturn = @PageSize * (@PageIndex + 1)    
SET @PageLowerBound = @PageSize * @PageIndex
SET @PageUpperBound = @PageLowerBound + @PageSize + 1

--Create table to store Customer Role Ids
CREATE TABLE #Roles
(
    CustomerRoleId int
)

--Check to see if there is any Customer Roles to search on
IF @CustomerRoles IS NOT NULL
BEGIN
    INSERT INTO #Roles
        SELECT CAST(data as int) FROM [nop_splitstring_to_table](@CustomerRoles, ',')
END

CREATE TABLE #ReturnData
(
    Id int IDENTITY (1, 1) NOT NULL,
    CustomerId int,
    FullName nvarchar(MAX),
    Username nvarchar(1000),
    UnitId int,
    UnitName nvarchar(MAX),
    CustomerRoles nvarchar(MAX),
    AddressId int,
    Location nvarchar(MAX),
    TM nvarchar(MAX),
    Phone nvarchar(MAX),
    Active bit,
    CreatedOnUtc datetime,
    LastActivityDateUtc datetime,
    CustomerGuid uniqueidentifier,
    Email nvarchar(1000),
    [Password] nvarchar(MAX),
    PasswordFormatId int,
    PasswordSalt nvarchar(MAX),
    AdminComment nvarchar(MAX),
    LanguageId int,
    CurrencyId int,
    TaxDisplayTypeId int,
    IsTaxExempt bit,
    VatNumber nvarchar(MAX),
    VatNumberStatusId int,
    SelectedPaymentMethodSystemName nvarchar(MAX),
    CheckoutAttributes nvarchar(MAX),
    DiscountCouponCode nvarchar(MAX),
    GiftCardCouponCodes nvarchar(MAX),
    UseRewardPointsDuringCheckout bit,
    TimeZoneId nvarchar(MAX),
    AffiliateId int,
    Deleted bit,
    IsSystemAccount bit,
    SystemName nvarchar(MAX),
    LastIpAddress nvarchar(MAX),
    LastLoginDateUtc datetime,
    OldEmployeeId int,
    OldId int,
    BillingAddress_Id int,
    ShippingAddress_Id int,
    CJISBillingAddress_Id int,
    CJISShippingAddress_Id int
)

SET @SQL = 'INSERT INTO #ReturnData
                SELECT Distinct C.Id AS CustomerId, IsNULL(dbo.GetFullName(C.Id), '''') AS FullName,
                    C.Username, C.UnitId, dbo.GetUnitText(C.UnitId) AS UnitName,
                    dbo.GetCustomerRoles(C.Id) AS CustomerRoles, CA.Id AS AddressId,
                    CA.Location, CA.TM, CA.Phone, C.Active, C.CreatedOnUtc, C.LastActivityDateUtc,
                    C.CustomerGuid, C.Email, C.[Password], C.PasswordFormatId,
                    C.PasswordSalt, C.AdminComment, C.LanguageId, C.CurrencyId,
                    C.TaxDisplayTypeId, C.IsTaxExempt, C.VatNumber, C.VatNumberStatusId,
                    C.SelectedPaymentMethodSystemName, C.CheckoutAttributes,
                    C.DiscountCouponCode, C.GiftCardCouponCodes, C.UseRewardPointsDuringCheckout,
                    C.TimeZoneId, C.AffiliateId, C.Deleted, C.IsSystemAccount, C.SystemName,
                    C.LastIpAddress, C.LastLoginDateUtc, C.OldEmployeeId, C.OldId,
                    C.BillingAddress_Id, C.ShippingAddress_Id, C.CJISBillingAddress_Id,
                    C.CJISShippingAddress_Id
                FROM Customer C
                    LEFT JOIN Customer_CustomerRole_Mapping CCRM ON C.Id = CCRM.Customer_Id
                    LEFT JOIN CustomerCJISAddresses CCA ON C.Id = CCA.Customer_Id
                    LEFT JOIN CJISAddress CA ON CCA.CJISAddress_Id = CA.Id
                        AND CA.IsPrimary = 1
                    LEFT JOIN GenericAttribute GA ON GA.KeyGroup = ''Customer''
                        AND (GA.[Key] = ''FirstName'' OR GA.[Key] = ''LastName'')
                        AND C.Id = GA.EntityId '

IF @CustomerRoles IS NOT NULL
BEGIN
    SET @SQL = @SQL + 'WHERE CCRM.CustomerRole_Id IN (SELECT CustomerRoleId FROM #Roles) '
END

IF @IsActive IS NOT NULL
BEGIN
    --Do a check to see if the 'Where' clause already exists
    IF  dbo.GetWhereCheck(@SQL) = 1
    BEGIN
        SET @SQL = @SQL + 'AND C.Active = @IsActive '
    END
    --'Where' clause doesn't exist yet
    ELSE
    BEGIN
        SET @SQL = @SQL + 'WHERE C.Active = @IsActive '
    END
END

IF @Username IS NOT NULL
BEGIN
    --Do a check to see if the 'Where' clause already exists
    IF  dbo.GetWhereCheck(@SQL) = 1
    BEGIN
        SET @SQL = @SQL + 'AND C.Username LIKE ''' + @Username + ''' '
    END
    --'Where' clause doesn't exist yet
    ELSE
    BEGIN
        SET @SQL = @SQL + 'WHERE C.Username LIKE ''' + @Username + ''' '
    END
END

IF @FirstName IS NOT NULL
BEGIN
    --Do a check to see if the 'Where' clause already exists
    IF  dbo.GetWhereCheck(@SQL) = 1
    BEGIN
        SET @SQL = @SQL + 'AND (GA.[Key] = ''FirstName'' AND GA.[Value] LIKE ''' + @FirstName + ''') '
    END
    --'Where' clause doesn't exist yet
    ELSE
    BEGIN
        SET @SQL = @SQL + 'WHERE (GA.[Key] = ''FirstName'' AND GA.[Value] LIKE ''' + @FirstName + ''') '
    END
END

IF @LastName IS NOT NULL
BEGIN
    --Do a check to see if the 'Where' clause already exists
    IF  dbo.GetWhereCheck(@SQL) = 1
    BEGIN
        SET @SQL = @SQL + 'AND (GA.[Key] = ''LastName'' AND GA.[Value] LIKE ''' + @LastName + ''') '
    END
    --'Where' clause doesn't exist yet
    ELSE
    BEGIN
        SET @SQL = @SQL + 'WHERE (GA.[Key] = ''LastName'' AND GA.[Value] LIKE ''' + @LastName + ''') '
    END
END

IF @UnitId IS NOT NULL
BEGIN
    --Do a check to see if the 'Where' clause already exists
    IF  dbo.GetWhereCheck(@SQL) = 1
    BEGIN
        SET @SQL = @SQL + 'AND C.UnitId = @UnitId '
    END
    --'Where' clause doesn't exist yet
    ELSE
    BEGIN
        SET @SQL = @SQL + 'WHERE C.UnitId = @UnitId '
    END
END

--Do Order By
DECLARE @OrderByText nvarchar(50)
SET @OrderByText = 'Order By '
SET @OrderByText = @OrderByText + 
    CASE
        WHEN @SortBy = 0 THEN 'C.CreatedOnUtc DESC'
        WHEN @SortBy = 1 THEN 'C.CreatedOnUtc ASC'
        WHEN @SortBy = 2 THEN 'C.Username ASC'
        WHEN @SortBy = 3 THEN 'C.Username DESC'
        WHEN @SortBy = 4 THEN 'FullName ASC'
        WHEN @SortBy = 5 THEN 'FullName DESC'
        WHEN @SortBy = 6 THEN 'UnitName ASC'
        WHEN @SortBy = 7 THEN 'UnitName DESC'
        WHEN @SortBy = 8 THEN 'CustomerRoles ASC'
        WHEN @SortBy = 9 THEN 'CustomerRoles DESC'
        WHEN @SortBy = 10 THEN 'C.Active ASC'
        WHEN @SortBy = 11 THEN 'C.Active DESC'
        WHEN @SortBy = 12 THEN 'C.LastActivityDateUtc ASC'
        WHEN @SortBy = 13 THEN 'C.LastActivityDateUtc DESC'
        WHEN @SortBy = 14 THEN 'CA.Location ASC'
        WHEN @SortBy = 15 THEN 'CA.Location DESC'
        WHEN @SortBy = 16 THEN 'CA.TM ASC'
        WHEN @SortBy = 17 THEN 'CA.TM DESC'
        WHEN @SortBy = 18 THEN 'CA.Phone ASC'
        WHEN @SortBy = 19 THEN 'CA.Phone DESC'
END;

SET @SQL = @SQL + @OrderByText

EXEC sp_executesql @SQL,
N'@IsActive bit, @UnitId int',
@IsActive, @UnitId

DECLARE @DuplicateFields int
SET @TotalRecords = @@ROWCOUNT

DELETE FROM dupes
FROM #ReturnData dupes,
    #ReturnData fullTable
WHERE dupes.CustomerId = fullTable.CustomerId
    AND dupes.AddressId IS NULL
    AND dupes.Id < fullTable.Id

SET @DuplicateFields = @@ROWCOUNT
SET @TotalRecords = @TotalRecords - @DuplicateFields

DBCC CHECKIDENT (#ReturnData, RESEED, 0)

SELECT TOP (@RowsToReturn) CustomerId AS Id,
    Username, UnitId, Active, CreatedOnUtc,
    LastActivityDateUtc, CustomerGuid,
    Email, [Password], PasswordFormatId, PasswordSalt,
    AdminComment, LanguageId, CurrencyId, TaxDisplayTypeId,
    IsTaxExempt, VatNumber, VatNumberStatusId,
    SelectedPaymentMethodSystemName, CheckoutAttributes,
    DiscountCouponCode, GiftCardCouponCodes,
    UseRewardPointsDuringCheckout, TimeZoneId, AffiliateId,
    Deleted, IsSystemAccount, SystemName, LastIpAddress,
    LastLoginDateUtc, OldEmployeeId, OldId, BillingAddress_Id,
    ShippingAddress_Id, CJISBillingAddress_Id,
    CJISShippingAddress_Id
FROM #ReturnData
WHERE Id > @PageLowerBound
    AND Id < @PageUpperBound

DROP TABLE #Roles
DROP TABLE #ReturnData
END

1 个答案:

答案 0 :(得分:3)

只需使用带有ROW_NUMBER()的标识列生成无间隙的数字,然后根据行号而不是Id列进行查询:

;With OrderedRows as (
    SELECT CustomerId AS Id,
    Username, UnitId, Active, CreatedOnUtc,
    LastActivityDateUtc, CustomerGuid,
    Email, [Password], PasswordFormatId, PasswordSalt,
    AdminComment, LanguageId, CurrencyId, TaxDisplayTypeId,
    IsTaxExempt, VatNumber, VatNumberStatusId,
    SelectedPaymentMethodSystemName, CheckoutAttributes,
    DiscountCouponCode, GiftCardCouponCodes,
    UseRewardPointsDuringCheckout, TimeZoneId, AffiliateId,
    Deleted, IsSystemAccount, SystemName, LastIpAddress,
    LastLoginDateUtc, OldEmployeeId, OldId, BillingAddress_Id,
    ShippingAddress_Id, CJISBillingAddress_Id,
    CJISShippingAddress_Id,
    ROW_NUMBER() OVER (ORDER BY Id) as rn
FROM #ReturnData
)
select * from OrderedRows where 
WHERE rn > @PageLowerBound
    AND rn < @PageUpperBound

演示drop column / add column方法并不总是有效。在我的机器上测试了一个基本上是空的数据库(当然,不能保证它会在其他机器上100%重现。我的Windows 7 64但是,SQL Server 2012):

create table #T (ID int IDENTITY(1,1) not null,rn int not null,
                 SpaceWaster char(900) not null)
;With PlentyRows as (
    select ROW_NUMBER() OVER (ORDER BY so1.object_id) as rn
    from sys.objects so1,sys.objects so2,sys.objects so3
)
insert into #T (rn,SpaceWaster)
select rn,'' from PlentyRows
order by rn

select * from #T where rn!=ID

alter table #T drop column id
alter table #T add ID int IDENTITY(1,1) not null

select * from #T where rn!=ID

drop table #T

第一个select * from #T where rn!=ID始终生成一个空结果集,然后对于第二个结果集,它返回所有行,第一个行的rn为2177,{{1} 1。