我目前正在开发一个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
答案 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。