Làm thế nào để bạn đặt hàng theo một tham số?


16

Chỉ tự hỏi liệu tôi có thể thu hút một số phản hồi về một thủ tục được lưu trữ mà tôi đang chạy hay không và liệu có cách xử lý tình huống hiệu quả hơn không (tôi khá chắc chắn sẽ có!).

Về cơ bản, tôi có một SP duy nhất mà tôi gọi để trả về danh sách các bản ghi (Công việc) có thể có một hoặc nhiều trạng thái và thứ tự sắp xếp (Tôi đang sử dụng RowNum để phân trang). Hiện tại tôi đang sử dụng VỚI RECOMPILE vì các biến thể của trạng thái có thể thay đổi mọi lúc (tùy thuộc vào người dùng, v.v.). Cũng có một số bộ lọc đang diễn ra.

Tôi đang sử dụng một câu lệnh IF để chạy cùng một đoạn mã với thay đổi duy nhất là thứ tự sắp xếp.

Tôi đoán câu hỏi của tôi là: Có cách nào tốt hơn để làm điều này (có thể là các SP khác nhau cho các trạng thái khác nhau) không? Tôi có quá phức tạp mọi thứ do thiếu kiến ​​thức (rất có thể) SP thực sự ổn, nhưng yêu cầu một số điều chỉnh nhỏ để giảm số lượng dòng?

Tôi đã dán một phần của SP bên dưới - sự khác biệt duy nhất cho mã đầy đủ là các câu lệnh IF bổ sung cho các đơn hàng sắp xếp khác nhau ...

Tôi đánh giá cao bất kỳ thông tin phản hồi.

Cảm ơn trước!

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 để sắp xếp cột khác

Câu trả lời:


16

Việc sắp xếp có thể được thực hiện với biểu thức CASE, một cái gì đó dọc theo dòng:

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

Bạn có thể muốn xem xét lại OR'd khi có điều kiện vì chúng có khả năng tạo ra các kế hoạch kém. Một trong những bài viết hay nhất mà tôi đã đọc về điều này (và các phương pháp thay thế) là Điều kiện tìm kiếm động trong T-SQL

Chỉnh sửa: Nhìn lại danh sách tham số của bạn, các bộ lọc chính xuất hiện là @CustomerId và @UserId. Tôi khuyên bạn nên tạo hai procs, spJobs_SelectByCustomerId và spJobs_SelectByUserId, để lọc theo các tham số tương ứng của chúng để bạn loại bỏ các điều kiện '@Param = 0 hoặc Cột = @Param'. Tôi đoán thông số quan trọng tiếp theo là @ShowCompleted (giả sử rằng một khi công việc đã hoàn thành, nó sẽ không được hiển thị trừ khi @ ShowCompleted = 1), mà tôi sẽ xem xét bao gồm trong các chỉ mục trên CustomerId và UserId.

Edit2: Hài hước làm sao những câu hỏi này đôi khi xuất hiện trong đầu bạn! :) Khi lập chỉ mục @ShowCompleted, đây là một trong những trường hợp sử dụng Cột BIT có độ chọn lọc thấp Đầu tiên có thể là Chiến lược tốt nhất . Chỉ số được lọc cũng nên được xem xét.


Wooosh! Tất cả thẳng qua đầu tôi, nhưng tôi không sợ đọc và học! Cảm ơn Mark đã dành thời gian để trả lời. Thật là buồn cười khi tiềm thức tiếp tục làm việc thông qua những điều này. Tôi cũng tìm thấy sự giúp đỡ của bia và nicotine :)
ShakeNZ

Nếu bất cứ điều gì cần làm rõ, vui lòng mở rộng câu hỏi của bạn hoặc bắt đầu một bài viết mới.
Mark Storey-Smith

1
Cảm ơn Mark. Tôi đã thực hiện một số đề xuất của bạn và tất cả đều tốt ngoại trừ một vấn đề kỳ lạ ... Tôi đã đăng trên một chủ đề khác: dba.stackexchange.com/questions/4162/ Thẻ
sóngNZ

Thật tệ, tôi đã không giải thích rằng bạn phải đối phó với các loại khác nhau trong các biểu thức trường hợp riêng biệt. Đã thêm một câu trả lời cho câu hỏi mới của bạn.
Mark Storey-Smith

giải pháp này ( CASEdựa trên cơ sở) có tạo ra một kế hoạch thực hiện kém không? Điều này sẽ không CASEđược đánh giá cho mỗi hàng?
Andrei Rînea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.