it-swarm.com.de

Wie ordnen Sie nach einem Parameter?

Ich frage mich nur, ob ich Feedback zu einer von mir ausgeführten gespeicherten Prozedur einholen könnte und ob es eine effizientere Möglichkeit gibt, mit dem Szenario umzugehen (ich bin mir ziemlich sicher, dass es eine geben wird!).

Grundsätzlich habe ich ein einzelnes SP, das ich aufrufe, um eine Liste von Datensätzen (Jobs) zurückzugeben, die einen oder mehrere Status und eine Sortierreihenfolge haben können (ich verwende RowNum für das Paging) Moment, in dem ich WITH RECOMPILE verwende, weil sich die Variationen der Status ständig ändern können (abhängig vom Benutzer usw.). Es wird auch gefiltert.

Ich verwende eine IF-Anweisung, um im Wesentlichen dasselbe Codebit auszuführen, wobei die einzige Änderung die Sortierreihenfolge ist.

Ich denke, meine Fragen sind: Gibt es eine bessere Möglichkeit, dies zu tun (möglicherweise unterschiedliche SPs für unterschiedliche Status)? Überkompliziere ich Dinge aufgrund mangelnden Wissens (ziemlich wahrscheinlich)? Ist das SP tatsächlich in Ordnung, erfordert jedoch geringfügige Änderungen, um die Anzahl der Zeilen zu verringern?

Ich habe einen Teil der SP unten - der einzige Unterschied zum vollständigen Code sind die zusätzlichen IF-Anweisungen für die verschiedenen Sortierreihenfolgen eingefügt ...

Ich würde mich über Feedback freuen.

Danke im Voraus!

PROCEDURE [dbo].[sp_Jobs] 

@PageNumber int, 
@PageSize int, 
@FilterExpression varchar(500), 
@OrderBy varchar(50), 
@CustomerID int, 
@ShowNotSet bit, 
@ShowPlaced bit, 
@ShowProofed bit, 
@ShowReProofed bit, 
@ShowApproved bit, 
@ShowOnTime bit, 
@ShowLate bit, 
@ShowProblem bit, 
@ShowCompleted bit, 
@ShowDispatched bit, 
@ShowUnapproved bit, 
@ShowClosed bit, 
@ShowReturned bit, 
@UserID int

WITH RECOMPILE 

AS

--JobNumber DESC 
if @OrderBy='JobNumberDESC' 
BEGIN 

WITH Keys AS (SELECT TOP (@PageNumber * @PageSize) ROW_NUMBER() OVER (ORDER BY JobNumber DESC) as rn,P1.jobNumber,P1.CustID,P1.DateIn,P1.DateDue,P1.DateOut,p1.client,p1.MasterJobStatusID,p1.MasterJobStatusTimestamp,p1.OwnerID 

FROM 
vw_Jobs_List P1 WITH (NOLOCK) 

WHERE 
(@CustomerID = 0 OR CustID = @CustomerID) 
AND (@UserID = 0 OR OwnerID = @UserID) 
AND ((@ShowNotSet = 1 AND MasterJobStatusID=1) OR (@ShowPlaced = 1 AND MasterJobStatusID=2) OR (@ShowProofed = 1 AND MasterJobStatusID=3) OR (@ShowReProofed = 1 AND MasterJobStatusID=4) OR (@ShowApproved = 1 AND MasterJobStatusID=5) OR (@ShowOnTime = 1 AND MasterJobStatusID=6) OR (@ShowLate = 1 AND MasterJobStatusID=7) OR (@ShowProblem = 1 AND MasterJobStatusID=8) OR (@ShowCompleted = 1 AND MasterJobStatusID=9) OR (@ShowDispatched = 1 AND MasterJobStatusID=10) OR (@ShowUnapproved = 1 AND MasterJobStatusID=11) OR (@ShowClosed = 1 AND MasterJobStatusID=12) OR (@ShowReturned = 1 AND MasterJobStatusID=13)) AND (Search LIKE '%'[email protected]+'%')

ORDER BY 
P1.JobNumber DESC ),SelectedKeys AS (
SELECT TOP (@PageSize)SK.rn,SK.JobNumber,SK.CustID,SK.DateIn,SK.DateDue,SK.DateOut 

FROM 
Keys SK 

WHERE 
SK.rn > ((@PageNumber-1) * @PageSize) 

ORDER BY 
SK.JobNumber DESC) 

SELECT SK.rn,J.JobNumber,J.OwnerID,J.Description,J.Client,SK.CustID,OrderNumber, CAST(DateAdd(d, -2, CAST(isnull(SK.DateIn,0) AS DateTime)) AS nvarchar) AS DateIn, CAST(DateAdd(d, -2, CAST(isnull(SK.DateDue,0) AS DateTime)) AS nvarchar) AS DateDue,CAST(DateAdd(d, -2, CAST(isnull(SK.DateOut,0) AS DateTime)) AS nvarchar) AS DateOut, Del_Method,Ticket#, InvoiceEmailed, InvoicePrinted, InvoiceExported, InvoiceComplete, JobStatus,j.MasterJobStatusID,j.MasterJobStatusTimestamp,js.MasterJobStatus 

FROM SelectedKeys SK JOIN vw_Jobs_List J WITH (NOLOCK) ON j.JobNumber=SK.JobNumber JOIN tbl_SYSTEM_MasterJobStatus js WITH (NOLOCK) ON j.MasterJobStatusID=js.MasterJobStatusID 

ORDER BY 
SK.JobNumber DESC 
END

--ELSE IF für andere Spaltensortierung

16
VaticNZ

Die Sortierung kann mit einem CASE-Ausdruck erledigt werden, ähnlich wie folgt:

ORDER BY
    CASE WHEN @SortDirection = 'A' THEN
        CASE 
           WHEN @SortBy = 'JobNumber' THEN JobNumber
           WHEN @SortBy = 'JobId' THEN JobId 
        END
    END ASC
    , CASE WHEN @SortDirection = 'D' THEN
        CASE 
           WHEN @SortBy = 'JobNumber' THEN JobNumber
           WHEN @SortBy = 'JobId' THEN JobId 
        END
    END DESC

Möglicherweise möchten Sie den OP unter bestimmten Bedingungen überdenken, da diese wahrscheinlich zu schlechten Plänen führen. Einer der besten Artikel, den ich über dieses (und die alternativen Ansätze) gelesen habe, ist Dynamische Suchbedingungen in T-SQL

Bearbeiten: Wenn Sie sich Ihre Parameterliste noch einmal ansehen, scheinen die primären Filter @CustomerId und @UserId zu sein. Ich würde vorschlagen, zwei Prozesse zu erstellen, spJobs_SelectByCustomerId und spJobs_SelectByUserId, die nach ihren jeweiligen Parametern filtern, sodass Sie die Bedingungen '@Param = 0 oder Column = @Param' beseitigen. Ich denke, der nächste wichtige Parameter ist @ShowCompleted (vorausgesetzt, wenn ein Job einmal erledigt ist, wird er nur angezeigt, wenn @ ShowCompleted = 1), den ich in die Indizes der CustomerId und UserId aufnehmen würde.

Edit2: Komisch, wie diese Fragen manchmal im Hinterkopf auftauchen! :) Bei der Indizierung von @ShowCompleted ist dies eine der Situationen, in denen Verwenden einer BIT-Spalte mit niedriger Selektivität zuerst die beste Strategie sein kann . Gefilterte Indizes sollten ebenfalls berücksichtigt werden.

16