매개 변수를 어떻게 주문합니까?


16

내가 실행중인 저장 프로 시저에 대한 피드백을 요청할 수 있는지, 시나리오를 처리하는보다 효율적인 방법이 있는지 궁금해합니다 (확실히있을 것입니다!).

기본적으로 하나 이상의 상태와 정렬 순서가있는 레코드 목록 (작업)을 반환하기 위해 호출하는 단일 SP가 있습니다 (Paging에 RowNum을 사용하고 있습니다). 현재 상태를 변경하면 사용자 등에 따라 항상 변경 될 수 있으므로 WITH RECOMPILE을 사용하고 있습니다. 필터링도 진행 중입니다.

나는 본질적으로 동일한 순서의 코드를 정렬 순서로 변경하기 위해 IF 문을 사용하고 있습니다.

내 질문은 다음과 같습니다.이 작업을 수행하는 더 좋은 방법이 있습니까 (상태에 따라 SP가 다를 수 있음)? 지식이 부족하여 일을 너무 복잡하게 만들었습니까 (아마도) SP가 실제로 괜찮습니까?

SP의 일부를 아래에 붙여 넣었습니다. 전체 코드의 유일한 차이점은 다른 정렬 순서에 대한 추가 IF 문입니다 ...

의견을 보내 주셔서 감사합니다.

미리 감사드립니다!

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 '%'+@FilterExpression+'%')

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

답변:


16

정렬은 CASE 표현식을 사용하여 처리 할 수 ​​있습니다.

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

잘못된 계획을 생성 할 수있는 조건이있는 OR을 다시 고려할 수 있습니다. 내가 읽은 최고의 기사 중 하나 (및 다른 방법)는 T-SQL의 동적 검색 조건입니다.

편집 : 매개 변수 목록을 다시 보면 기본 필터는 @CustomerId 및 @UserId로 나타납니다. spJobs_SelectByCustomerId 및 spJobs_SelectByUserId라는 두 가지 procs를 만들어 각 매개 변수로 필터링하여 '@Param = 0 또는 Column = @Param'조건을 제거하는 것이 좋습니다. 다음으로 중요한 매개 변수는 @ShowCompleted (작업이 '완료'되면 @ ShowCompleted = 1이 아니라면 표시되지 않는다고 가정)이며 CustomerId 및 UserId의 색인에 포함시키는 것으로 간주됩니다.

Edit2 :이 질문들이 때때로 당신의 마음의 뒤에서 똑딱 거리는 방식이 재미 있습니다! :) @ShowCompleted를 인덱싱 할 때 낮은 선택도의 BIT 열을 사용하는 것이 최선의 전략이 될 수 있는 경우 중 하나입니다 . 필터링 된 인덱스 도 고려해야합니다.


우우! 내 머리 위로 똑바로 읽었지만 배우고 두려워하지 않습니다! 시간을내어 답변 해 주셔서 감사합니다. 아종이 어떻게 이런 일들을 계속 하는가는 정말 재밌습니다. 나도 맥주와 니코틴의 도움을
받는다

설명이 필요한 경우 언제든지 질문을 확장하거나 새 게시물을 시작하십시오.
Mark Storey-Smith

1
고마워 마크. 나는 당신의 제안 중 일부를 구현했으며 이상한 문제를 제외하고 모두 훌륭합니다 ... 나는 다른 스레드에 게시했습니다 : dba.stackexchange.com/questions/4162/…
VaticNZ

내 나쁜, 당신은 별도의 사례 표현에서 다른 유형을 처리해야한다고 설명하지 않았습니다. 새 질문에 대한 답변을 추가했습니다.
Mark Storey-Smith

이 솔루션 ( CASE기반)이 잘못된 실행 계획을 생성하지 않습니까? 이것은 CASE각 행에 대해 평가 되지 않습니까?
Andrei Rînea
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.