1

我有几个动态构建的查询,在 and 列上有一个复合主tblWarr_SWH_WarrCLHD_35键。[Account No]tblWarr_SWH_WarrCLHD_35.[Claim No]

最近出现了一个新要求,要求我们在结果中提供例外,因此用户可以要求通过[Account No]和过滤掉每一行[Claim No]。将有不确定数量的行异常。

[Account No]客户传递例外列表和[Claim No]组合的最佳方法是什么?

我需要传入一个字符串并在 T-SQL 中解析它吗?我可以这样建造

AND NOT ([Account No] = 'abc' AND [Claim No] = 'cde') 
AND NOT ([Account No] = 'fgh' AND [Claim No] = 'ijk')

结果通过带有两个表格的类型化数据集显示给客户端软件。

原始数据

DECLARE @SQL nvarchar(4000)
DECLARE @SQLWhere nvarchar(4000) 
DECLARE @SQLOrder nvarchar(MAX)

SET @SQL = 'SELECT tblWarr_SWH_WarrCLHD_35.[Account No], tblWarr_SWH_WarrCLHD_35.[Claim No], tblWarr_SWH_WarrCLHD_35.ClaimCost, 
                      tblWarr_SWH_WarrCLHD_35.[Serial No], tblWarr_SMT_MCType_47.[Machine Type], tblWarr_SMH_MCHist_34.[Date Built], 
                      tblWarr_SMH_MCHist_34.[Date Sold], tblWarr_SVC_ServiceCodes.[Service Code], tblWarr_DefectCodes.Code AS [Defect Code], 
                      tblWarr_SPN_PartNo_01.[Part No], tblWarr_SPN_PartNo_01.[Part Description], tblWarr_SWH_WarrCLHD_35.[Failed Part No Qty], 
                      tblWarr_MachineHours.[Machine Hours At Failure], tblWarr_SWH_WarrCLHD_35.[Claim Date], tblWarr_SNA_WarNar_77.Narrative, 
                      tblWarr_SSU_Supplier_09.[Supplier Name],tblWarr_SWH_WarrCLHD_35.[ClaimStateID]
                FROM tblWarr_SMH_MCHist_34 INNER JOIN
                      tblWarr_SWH_WarrCLHD_35 ON tblWarr_SMH_MCHist_34.[Serial No] = tblWarr_SWH_WarrCLHD_35.[Serial No] INNER JOIN
                      tblWarr_SMT_MCType_47 ON tblWarr_SMH_MCHist_34.MachineTypeID = tblWarr_SMT_MCType_47.ID INNER JOIN
                      tblWarr_SVC_ServiceCodes ON tblWarr_SWH_WarrCLHD_35.ServiceCodeFullID = tblWarr_SVC_ServiceCodes.ID INNER JOIN
                      tblWarr_DefectCodes ON tblWarr_SWH_WarrCLHD_35.DefectCodeID = tblWarr_DefectCodes.ID INNER JOIN
                      tblWarr_SPN_PartNo_01 ON tblWarr_SWH_WarrCLHD_35.FailedPartNoID = tblWarr_SPN_PartNo_01.ID INNER JOIN
                      tblWarr_MachineHours ON tblWarr_SWH_WarrCLHD_35.MachineHoursID = tblWarr_MachineHours.ID INNER JOIN
                      tblWarr_SNA_WarNar_77 ON tblWarr_SWH_WarrCLHD_35.NarrativeID = tblWarr_SNA_WarNar_77.ID INNER JOIN
                      tblWarr_SSU_Supplier_09 ON tblWarr_SWH_WarrCLHD_35.SupplierID = tblWarr_SSU_Supplier_09.ID'
SET @SQLWhere = ' WHERE ((tblWarr_SPN_PartNo_01.[Part No] = @_PartNumber) AND '
SET @SQLOrder = ' ORDER BY CAST(tblWarr_SMH_MCHist_34.[Date Built] AS smalldatetime) DESC'

IF (@ClaimDateFrom IS NOT NULL AND @ClaimDateTo IS NOT NULL)AND (LEN(@ClaimDateFrom) > 0 AND LEN(@ClaimDateTo) > 0)
    SET @SQLWhere = @SQLWhere + '(tblWarr_SWH_WarrCLHD_35.[Claim Date] BETWEEN @_ClaimDateFrom AND @_ClaimDateTo) AND '

IF (@BuildDateFrom IS NOT NULL AND @BuildDateTo IS NOT NULL)AND (LEN(@BuildDateFrom) > 0 AND LEN(@BuildDateTo) > 0)
    SET @SQLWhere = @SQLWhere + '(CAST(tblWarr_SMH_MCHist_34.[Date Built] AS SmalldateTime) BETWEEN @_BuildDateFrom AND @_BuildDateTo) AND '

IF (@ClaimStates IS NOT NULL)AND (LEN(@ClaimStates) > 0)
    SET @SQLWhere = @SQLWhere + '(tblWarr_SWH_WarrCLHD_35.[ClaimStateID] IN (SELECT value FROM Split(''' + ',' + ''',@_ClaimStates))) AND '

IF LEN(@SQLWhere) > 0
    SET @SQL = @SQL + LEFT(@SQLWhere, LEN(@SQLWhere)-4) + ')' + @SQLOrder

EXEC sp_executesql @SQL,
    N'@_PartNumber nvarchar(20), @_ClaimDateFrom smalldatetime, @_ClaimDateTo smalldatetime, @_BuildDateFrom smalldatetime, @_BuildDateTo smalldatetime, @_ClaimStates nvarchar(50)',
    @_PartNumber = @PartNumber, @_ClaimDateFrom = @ClaimDateFrom, @_ClaimDateTo = @ClaimDateTo, @_BuildDateFrom = @BuildDateFrom, @_BuildDateTo = @BuildDateTo, @_ClaimStates = @ClaimStates

聚合数据

DECLARE @SQL nvarchar(4000)
DECLARE @SQLWhere nvarchar(4000) 
DECLARE @SQLOrder nvarchar(MAX)
DECLARE @Date1 as nvarchar(5)   

SET @Date1 = '01/'

SET @SQL = 'SELECT CAST(@_Date1 + CAST(DATEPART(mm,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(2)) + ''' + '/' + ''' + CAST(DATEPART(yyyy,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(4)) as smalldatetime) AS ClaimDate , COUNT(tblWarr_SWH_WarrCLHD_35.[Claim No]) As FaultCount
                FROM tblWarr_SMH_MCHist_34 INNER JOIN
                      tblWarr_SWH_WarrCLHD_35 ON tblWarr_SMH_MCHist_34.[Serial No] = tblWarr_SWH_WarrCLHD_35.[Serial No] INNER JOIN
                      tblWarr_SMT_MCType_47 ON tblWarr_SMH_MCHist_34.MachineTypeID = tblWarr_SMT_MCType_47.ID INNER JOIN
                      tblWarr_SVC_ServiceCodes ON tblWarr_SWH_WarrCLHD_35.ServiceCodeFullID = tblWarr_SVC_ServiceCodes.ID INNER JOIN
                      tblWarr_DefectCodes ON tblWarr_SWH_WarrCLHD_35.DefectCodeID = tblWarr_DefectCodes.ID INNER JOIN
                      tblWarr_SPN_PartNo_01 ON tblWarr_SWH_WarrCLHD_35.FailedPartNoID = tblWarr_SPN_PartNo_01.ID INNER JOIN
                      tblWarr_MachineHours ON tblWarr_SWH_WarrCLHD_35.MachineHoursID = tblWarr_MachineHours.ID INNER JOIN
                      tblWarr_SNA_WarNar_77 ON tblWarr_SWH_WarrCLHD_35.NarrativeID = tblWarr_SNA_WarNar_77.ID INNER JOIN
                      tblWarr_SSU_Supplier_09 ON tblWarr_SWH_WarrCLHD_35.SupplierID = tblWarr_SSU_Supplier_09.ID'
SET @SQLWhere = ' WHERE ((tblWarr_SPN_PartNo_01.[Part No] = @_PartNumber) AND '
SET @SQLOrder = ' GROUP BY CAST(@_Date1 + CAST(DATEPART(mm,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(2)) + ''' + '/' + ''' + CAST(DATEPART(yyyy,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(4)) as smalldatetime) ORDER BY CAST(@_Date1 + CAST(DATEPART(mm,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(2)) + ''' + '/' + ''' + CAST(DATEPART(yyyy,CAST(tblWarr_SMH_MCHist_34.[Date Built] as smalldatetime)) as nvarchar(4)) as smalldatetime)'

IF (@ClaimDateFrom IS NOT NULL AND @ClaimDateTo IS NOT NULL)AND (LEN(@ClaimDateFrom) > 0 AND LEN(@ClaimDateTo) > 0)
    SET @SQLWhere = @SQLWhere + '(CAST(tblWarr_SWH_WarrCLHD_35.[Claim Date] AS SmalldateTime) BETWEEN @_ClaimDateFrom AND @_ClaimDateTo) AND '

IF (@BuildDateFrom IS NOT NULL AND @BuildDateTo IS NOT NULL)AND (LEN(@BuildDateFrom) > 0 AND LEN(@BuildDateTo) > 0)
    SET @SQLWhere = @SQLWhere + '(CAST(tblWarr_SMH_MCHist_34.[Date Built] AS SmalldateTime) BETWEEN @_BuildDateFrom AND @_BuildDateTo) AND '

IF (@ClaimStates IS NOT NULL)AND (LEN(@ClaimStates) > 0)
    SET @SQLWhere = @SQLWhere + '(tblWarr_SWH_WarrCLHD_35.[ClaimStateID] IN (SELECT value FROM Split(''' + ',' + ''',@_ClaimStates))) AND '

IF LEN(@SQLWhere) > 0
    SET @SQL = @SQL + LEFT(@SQLWhere, LEN(@SQLWhere)-4) + ')' + @SQLOrder

EXEC sp_executesql @SQL,
    N'@_PartNumber nvarchar(20), @_ClaimDateFrom smalldatetime, @_ClaimDateTo smalldatetime, @_BuildDateFrom smalldatetime, @_BuildDateTo smalldatetime, @_Date1 nvarchar(5), @_ClaimStates nvarchar(50) ',
    @_PartNumber = @PartNumber, @_ClaimDateFrom = @ClaimDateFrom, @_ClaimDateTo = @ClaimDateTo, @_BuildDateFrom = @BuildDateFrom, @_BuildDateTo = @BuildDateTo, @_Date1 = @Date1, @_ClaimStates = @ClaimStates
4

1 回答 1

1

我可以建议像这样传递异常:

"account_A,claim_1;account_B,claim_2;account_C,claim_3;"

然后,您可以创建一个函数来解析此字符串以返回一个表 @ExceptionAccountsAndClaims:

异常账户 | 例外声明

账户_A | 索赔_1

帐号_B | 索赔_2

帐号_C | 索赔_3

然后,在您的动态查询中,使用条件:

WHERE (SELECT COUNT(*) FROM @ExceptionAccountsAndClaim e WHERE tblWarr_SWH_WarrCLHD_35.[Account No] = e.ExceptionAccount AND tblWarr_SWH_WarrCLHD_35.[Claim No] = e.ExceptionClaim) = 0

注意:条件可能不是 100% 正确的。如果您愿意,请更正它以适合您。

祝你好运。

于 2012-08-29T13:48:55.860 回答