Sắp xếp động trong các thủ tục lưu trữ SQL


126

Đây là một vấn đề mà tôi đã dành hàng giờ để nghiên cứu trong quá khứ. Đối với tôi, dường như đây là điều cần được giải quyết bằng các giải pháp RDBMS hiện đại nhưng tôi chưa tìm thấy bất cứ điều gì thực sự giải quyết những gì tôi thấy là một nhu cầu cực kỳ phổ biến trong bất kỳ ứng dụng Web hoặc Windows nào có hỗ trợ cơ sở dữ liệu.

Tôi nói về sắp xếp năng động. Trong thế giới tưởng tượng của tôi, nó sẽ đơn giản như một thứ gì đó như:

ORDER BY @sortCol1, @sortCol2

Đây là ví dụ điển hình được đưa ra bởi các nhà phát triển SQL và Thủ tục lưu trữ mới trên tất cả các diễn đàn trên Internet. "Tại sao điều này là không thể?" họ hỏi. Lúc nào cũng vậy, cuối cùng ai đó cũng đến để giảng cho họ về bản chất tổng hợp của các thủ tục được lưu trữ, về các kế hoạch thực hiện nói chung và tất cả các lý do khác tại sao không thể đưa tham số trực tiếp vào một ORDER BYmệnh đề.


Tôi biết những gì một số bạn đã nghĩ: "Hãy để khách hàng thực hiện việc sắp xếp." Đương nhiên, điều này giảm tải công việc từ cơ sở dữ liệu của bạn. Tuy nhiên, trong trường hợp của chúng tôi, các máy chủ cơ sở dữ liệu của chúng tôi thậm chí không làm mất 99% thời gian và chúng thậm chí còn không có đa lõi hoặc bất kỳ cải tiến nào khác đối với kiến ​​trúc hệ thống xảy ra cứ sau 6 tháng. Vì lý do này thôi, việc cơ sở dữ liệu của chúng tôi xử lý việc sắp xếp sẽ không thành vấn đề. Ngoài ra, cơ sở dữ liệu rấtgiỏi phân loại. Họ được tối ưu hóa cho nó và đã có nhiều năm để làm cho đúng, ngôn ngữ để thực hiện nó rất linh hoạt, trực quan và đơn giản và trên hết là bất kỳ nhà văn SQL mới bắt đầu nào cũng biết cách làm và thậm chí quan trọng hơn là họ biết cách chỉnh sửa nó, thực hiện thay đổi, bảo trì, v.v. Khi cơ sở dữ liệu của bạn không bị đánh thuế và bạn chỉ muốn đơn giản hóa (và rút ngắn!) thời gian phát triển này có vẻ như là một lựa chọn rõ ràng.

Sau đó là vấn đề web. Tôi đã chơi với JavaScript để sắp xếp các bảng HTML phía máy khách, nhưng chắc chắn chúng không đủ linh hoạt cho nhu cầu của tôi và, một lần nữa, vì cơ sở dữ liệu của tôi không bị đánh thuế quá mức và có thể thực hiện sắp xếp thực sự dễ dàng, tôi có một thời gian khó khăn để chứng minh thời gian cần thiết để viết lại hoặc cuộn trình sắp xếp JavaScript của riêng tôi. Điều tương tự thường xảy ra đối với việc sắp xếp phía máy chủ, mặc dù nó có lẽ đã được ưa thích hơn JavaScript. Tôi không phải là người đặc biệt thích phần trên của DataSets, vì vậy hãy kiện tôi.

Nhưng điều này mang lại điểm không thể - hay nói đúng hơn là không dễ dàng. Tôi đã thực hiện, với các hệ thống trước đó, một cách cực kỳ hack để có được sự sắp xếp động. Nó không đẹp, cũng không trực quan, đơn giản hoặc linh hoạt và một người viết SQL mới bắt đầu sẽ bị mất trong vài giây. Điều này có vẻ không phải là một "giải pháp" mà là một "sự phức tạp".


Các ví dụ sau đây không có nghĩa là để lộ bất kỳ loại thực tiễn tốt nhất hoặc phong cách mã hóa tốt hay bất cứ điều gì, cũng không phải là biểu hiện cho khả năng của tôi với tư cách là một lập trình viên T-SQL. Họ là những gì họ là và tôi hoàn toàn thừa nhận họ là khó hiểu, hình thức xấu, và chỉ đơn giản là hack.

Chúng tôi chuyển một giá trị số nguyên làm tham số cho một thủ tục được lưu trữ (hãy gọi tham số chỉ là "sắp xếp") và từ đó chúng tôi xác định một loạt các biến khác. Ví dụ: giả sử sắp xếp là 1 (hoặc mặc định):

DECLARE @sortCol1 AS varchar(20)
DECLARE @sortCol2 AS varchar(20)
DECLARE @dir1 AS varchar(20)
DECLARE @dir2 AS varchar(20)
DECLARE @col1 AS varchar(20)
DECLARE @col2 AS varchar(20)

SET @col1 = 'storagedatetime';
SET @col2 = 'vehicleid';

IF @sort = 1                -- Default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'asc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'asc';
END
ELSE IF @sort = 2           -- Reversed order default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'desc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'desc';
END

Bạn có thể thấy nếu tôi khai báo thêm các biến @colX để xác định các cột khác, tôi thực sự có thể sáng tạo với các cột để sắp xếp dựa trên giá trị của "sort" ... để sử dụng nó, nó thường trông giống như sau mệnh đề cực kỳ lộn xộn:

ORDER BY
    CASE @dir1
        WHEN 'desc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir1
        WHEN 'asc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END,
    CASE @dir2
        WHEN 'desc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir2
        WHEN 'asc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END

Rõ ràng đây là một ví dụ rất bị tước bỏ. Các công cụ thực sự, vì chúng ta thường có bốn hoặc năm cột để hỗ trợ sắp xếp, mỗi cột có thể là thứ cấp hoặc thậm chí là cột thứ ba để sắp xếp thêm vào đó (ví dụ: ngày giảm dần sau đó được sắp xếp theo thứ tự tăng dần) và mỗi cột hỗ trợ phân loại định hướng có hiệu quả gấp đôi số lượng các trường hợp. Vâng ... nó có lông rất nhanh.

Ý tưởng là người ta có thể "dễ dàng" thay đổi các trường hợp sắp xếp sao cho phương tiện được sắp xếp trước thời gian lưu trữ ... nhưng tính linh hoạt giả, ít nhất là trong ví dụ đơn giản này, thực sự kết thúc ở đó. Về cơ bản, mỗi trường hợp không thực hiện kiểm tra (vì phương pháp sắp xếp của chúng tôi không áp dụng cho lần này) sẽ hiển thị giá trị NULL. Và do đó, bạn kết thúc với một mệnh đề có chức năng như sau:

ORDER BY NULL DESC, NULL, [storagedatetime] DESC, blah blah

Bạn có được ý tưởng. Nó hoạt động vì SQL Server thực sự bỏ qua các giá trị null theo các mệnh đề. Điều này cực kỳ khó để duy trì, vì bất kỳ ai có bất kỳ kiến ​​thức làm việc cơ bản nào về SQL đều có thể thấy. Nếu tôi mất bất kỳ ai trong số các bạn, đừng cảm thấy tồi tệ. Chúng tôi đã mất một thời gian dài để làm cho nó hoạt động và chúng tôi vẫn bối rối khi cố gắng chỉnh sửa nó hoặc tạo ra những cái mới như nó. Rất may, nó không cần thay đổi thường xuyên, nếu không nó sẽ nhanh chóng trở thành "không đáng để gặp rắc rối."

Tuy nhiên, nó đã làm việc.


Câu hỏi của tôi là: có cách nào tốt hơn không?

Tôi ổn với các giải pháp khác ngoài các giải pháp Thủ tục được lưu trữ, vì tôi nhận ra rằng nó có thể không phải là con đường để đi. Tốt hơn là, tôi muốn biết liệu có ai có thể làm điều đó tốt hơn trong Quy trình được lưu trữ hay không, nhưng nếu không, làm thế nào để bạn xử lý cho phép người dùng tự động sắp xếp các bảng dữ liệu (theo hai hướng) với ASP.NET?

Và cảm ơn bạn đã đọc (hoặc ít nhất là đọc lướt qua) một câu hỏi dài như vậy!

PS: Rất vui vì tôi đã không hiển thị ví dụ về quy trình được lưu trữ hỗ trợ sắp xếp động, lọc động / tìm kiếm văn bản của các cột, phân trang thông qua ROWNUMBER () QUÁ, thử ... bắt lỗi với giao dịch quay lại lỗi ... "cỡ khổng lồ" thậm chí không bắt đầu mô tả chúng.


Cập nhật:

  • Tôi muốn tránh SQL động . Phân tích một chuỗi với nhau và chạy EXEC trên chuỗi đó đánh bại rất nhiều mục đích của việc có một thủ tục được lưu trữ ở vị trí đầu tiên. Đôi khi tôi tự hỏi mặc dù những khuyết điểm của việc làm một việc như vậy sẽ không đáng, ít nhất là trong những trường hợp sắp xếp động đặc biệt này. Tuy nhiên, tôi luôn cảm thấy bẩn bất cứ khi nào tôi thực hiện các chuỗi SQL động như thế - giống như tôi vẫn đang sống trong thế giới ASP cổ điển.
  • Rất nhiều lý do chúng tôi muốn các thủ tục được lưu trữ ở nơi đầu tiên là để bảo mật . Tôi không nhận được cuộc gọi về mối quan tâm bảo mật, chỉ đề xuất giải pháp. Với SQL Server 2005, chúng tôi có thể đặt quyền (trên cơ sở cho mỗi người dùng nếu cần) ở cấp lược đồ trên các quy trình được lưu trữ riêng lẻ và sau đó từ chối mọi truy vấn trực tiếp đối với các bảng. Phê bình những ưu và nhược điểm của phương pháp này có lẽ là cho một câu hỏi khác, nhưng một lần nữa, đó không phải là quyết định của tôi. Tôi chỉ là con khỉ mã chì. :)

Tham khảo stackoverflow.com/questions/3659981/ cũng vậy - SQL Server động ĐẶT HÀNG B BYNG với các kiểu dữ liệu hỗn hợp
LCJ

SQL động là cách ưu việt của FAR ... IF [và đây là IF lớn] .. Lớp truy cập dữ liệu của bạn rất nghiêm ngặt và SQL động của bạn được tạo bởi một hệ thống được lập trình cứng nhắc với các quy tắc RDBMS được thể hiện ở dạng hoàn hảo. Kiến trúc cơ sở dữ liệu được thiết kế theo thuật toán là một điều tuyệt vời ...
hajikelist

Câu trả lời:


97

Vâng, đó là một nỗi đau, và cách bạn đang làm nó trông giống như những gì tôi làm:

order by
case when @SortExpr = 'CustomerName' and @SortDir = 'ASC' 
    then CustomerName end asc, 
case when @SortExpr = 'CustomerName' and @SortDir = 'DESC' 
    then CustomerName end desc,
...

Điều này, với tôi, vẫn tốt hơn nhiều so với việc xây dựng SQL động từ mã, điều này biến thành cơn ác mộng về khả năng mở rộng và bảo trì cho các DBA.

Những gì tôi làm từ mã là cấu trúc lại phân trang và sắp xếp để tôi ít nhất không có nhiều sự lặp lại ở đó với các giá trị dân số cho @SortExpr@SortDir.

Theo như SQL có liên quan, hãy giữ thiết kế và định dạng giống nhau giữa các quy trình được lưu trữ khác nhau, để nó ít nhất là gọn gàng và dễ nhận biết khi bạn đi vào để thực hiện các thay đổi.


1
Chính xác. Mục tiêu của tôi là tránh thực hiện một lệnh EXEC trên chuỗi 5000 varchar lớn. Mọi thứ chúng ta làm phải được thực hiện thông qua các thủ tục được lưu trữ nếu chỉ để bảo mật được thêm vào vì chúng ta có thể đặt quyền cho chúng ở cấp lược đồ. Khả năng mở rộng và tăng hiệu suất chỉ là một điểm cộng trong trường hợp của chúng tôi.
Sean Hanley

1
Thêm khả năng bảo trì cho {bảo mật, khả năng mở rộng, hiệu suất}. Khi bạn có 3 hoặc 4 ứng dụng ngoài đó với SQL động chạy trên DB của bạn, bạn sẽ bị lừa, bạn không thể thay đổi bất cứ điều gì, đặc biệt là khi các ứng dụng và nhà phát triển tiếp tục phát triển. Exec và sql năng động là xấu xa.
Râu Eric Z

Chỉ vậy thôi --- chúng tôi đã làm, từ trước khi tôi đến đây, cho tất cả các ứng dụng web Classic ASP vẫn đang chạy và nhiều, nhiều ứng dụng Access VB vẫn đang lưu hành. Tôi co giật và phải kìm nén những thôi thúc để sửa chữa những lỗi chói lóa bất cứ khi nào tôi phải thực hiện bảo trì trên bất kỳ lỗi nào.
Sean Hanley

1
Đây cũng là những gì tôi làm, ngoại trừ tôi mã hóa hướng vào SortExpr: ORDER BY CASE WHEN sort = 'FirstName' THEN FirstName END ASC, CASE WHEN sort = '-FirstName' THEN FirstName END DESC
Michael Bray

Đây là cơn ác mộng đối với các DBA và các kỹ sư phần mềm. Vì vậy, thay vì có thể có các hệ thống năng động nhưng nghiêm ngặt tạo ra các câu lệnh SQL biểu cảm dựa trên lược đồ thông tin của bạn, bạn có cái nhìn kinh tởm về sự vô nghĩa mã hóa cứng này. Đó là chương trình kém ở mức tốt nhất.
hajikelist

23

Cách tiếp cận này giữ cho các cột có thể sắp xếp không bị trùng lặp hai lần theo thứ tự và IMO dễ đọc hơn một chút:

SELECT
  s.*
FROM
  (SELECT
    CASE @SortCol1
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol1,
    CASE @SortCol2
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol2,
    t.*
  FROM
    MyTable t) as s
ORDER BY
  CASE WHEN @dir1 = 'ASC'  THEN SortCol1 END ASC,
  CASE WHEN @dir1 = 'DESC' THEN SortCol1 END DESC,
  CASE WHEN @dir2 = 'ASC'  THEN SortCol2 END ASC,
  CASE WHEN @dir2 = 'DESC' THEN SortCol2 END DESC

Đây có vẻ là một câu trả lời hay nhưng dường như không hoạt động khi các cột có thể sắp xếp có các kiểu dữ liệu khác nhau
SlimSim


6

Các ứng dụng của tôi làm điều này rất nhiều nhưng tất cả chúng đều tự động xây dựng SQL. Tuy nhiên, khi tôi xử lý các thủ tục được lưu trữ, tôi làm điều này:

  1. Làm cho thủ tục được lưu trữ thành một hàm trả về một bảng các giá trị của bạn - không sắp xếp.
  2. Sau đó, trong mã ứng dụng của bạn làm một select * from dbo.fn_myData() where ... order by ...để bạn có thể tự động chỉ định thứ tự sắp xếp ở đó.

Sau đó, ít nhất là phần động trong ứng dụng của bạn, nhưng cơ sở dữ liệu vẫn đang thực hiện công việc nặng nhọc.


1
Đó có lẽ là sự thỏa hiệp tốt nhất mà tôi từng thấy giữa việc sử dụng SQL động và các thủ tục được lưu trữ cùng nhau. Tôi thích nó. Thỉnh thoảng tôi có thể thử nghiệm một cách tiếp cận tương tự, nhưng một sự thay đổi như vậy sẽ bị cấm trong bất kỳ dự án đang thực hiện nào của chúng tôi.
Sean Hanley

1
Bạn có thể đạt được điều tương tự bằng cách sử dụng biến bảng cục bộ thay vì dữ liệu bảng trả về dữ liệu. Tôi thấy các bảng cục bộ linh hoạt hơn các hàm, vì bạn có thể xuất một số thông tin gỡ lỗi.
Sanjay Zalke

5

Một kỹ thuật thủ tục được lưu trữ (hack?) Tôi đã sử dụng để tránh SQL động đối với một số công việc nhất định là có một cột sắp xếp duy nhất. I E,

SELECT
   name_last,
   name_first,
   CASE @sortCol WHEN 'name_last' THEN [name_last] ELSE 0 END as mySort
FROM
   table
ORDER BY 
    mySort

Cái này rất dễ bị đánh bại khi gửi - bạn có thể nối các trường trong cột mySort của mình, đảo ngược thứ tự với các hàm toán học hoặc ngày, v.v.

Mặc dù vậy, tốt hơn là tôi sử dụng các khung nhìn asp.net của tôi hoặc các đối tượng khác với sắp xếp tích hợp để thực hiện sắp xếp cho tôi SAU KHI truy xuất dữ liệu từ máy chủ Sql-Server. Hoặc ngay cả khi nó không được tích hợp sẵn - ví dụ: datatables, v.v. trong asp.net.


4

Có một vài cách khác nhau để bạn có thể hack cái này.

Điều kiện tiên quyết:

  1. Chỉ có một câu lệnh CHỌN trong sp
  2. Để lại bất kỳ sắp xếp (hoặc có một mặc định)

Sau đó chèn vào bảng tạm thời:

create table #temp ( your columns )

insert #temp
exec foobar

select * from #temp order by whatever

Phương pháp # 2: thiết lập một máy chủ được liên kết trở lại chính nó, sau đó chọn từ máy chủ này bằng openquery: http://www.sommarskog.se/share_data.html#OPENQUERY


4

Có thể có tùy chọn thứ ba, vì máy chủ của bạn có nhiều chu kỳ dự phòng - sử dụng quy trình trợ giúp để thực hiện sắp xếp thông qua bảng tạm thời. Cái gì đó như

create procedure uspCallAndSort
(
    @sql varchar(2048),        --exec dbo.uspSomeProcedure arg1,'arg2',etc.
    @sortClause varchar(512)    --comma-delimited field list
)
AS
insert into #tmp EXEC(@sql)
declare @msql varchar(3000)
set @msql = 'select * from #tmp order by ' + @sortClause
EXEC(@msql)
drop table #tmp
GO

Hãy cẩn thận: Tôi chưa thử nghiệm điều này, nhưng nó "nên" hoạt động trong SQL Server 2005 (sẽ tạo một bảng tạm thời từ tập kết quả mà không chỉ định trước các cột.)


2

Tại một số điểm, không đáng để di chuyển khỏi các thủ tục được lưu trữ và chỉ sử dụng các truy vấn được tham số hóa để tránh loại tin tặc này?


1
Trong một số trường hợp nhất định, có thể chúng là búa tạ trên móng tay, nhưng thường thì chúng tôi muốn đặt quyền (cụ thể là EXECUTE) trên các thủ tục được lưu trữ và không cho phép bất kỳ truy vấn SQL nào trực tiếp vào các bảng, thậm chí cả CHỌN. Tôi cũng không thích tin tặc, nhưng bảo mật không phải là lời kêu gọi của tôi.
Sean Hanley

1
Đây là lý do tại sao rất nhiều người đang chuyển sang Bản đồ quan hệ đối tượng. Không cần các chuyến đi khứ hồi để sắp xếp, các khối CASE khổng lồ cho cùng một bản cập nhật vô nghĩa cho hàng tấn cột khi thực sự chỉ cần một bản cập nhật, v.v. Đối số chiến thắng cho các thủ tục được lưu trữ vẫn còn là bảo mật.
Pittsburgh DBA

Tôi đang chuyển từ ORM (EF) sang thủ tục được lưu trữ vì ORM không hỗ trợ tìm kiếm toàn văn.
Ronnie Overby

@RonnieOverby Tìm kiếm toàn văn bản thường được phục vụ tốt hơn bởi một giải pháp chuyên dụng, ví dụ: Lucene.
Hank Gay

@HankGay Tôi có cảm giác kỳ lạ rằng khung thực thể cũng không hỗ trợ Lucene.
Ronnie Overby

2

Tôi đồng ý, sử dụng phía khách hàng. Nhưng có vẻ như đó không phải là câu trả lời bạn muốn nghe.

Vì vậy, nó là hoàn hảo theo cách nó là. Tôi không biết tại sao bạn muốn thay đổi nó, hoặc thậm chí hỏi "Có cách nào tốt hơn không." Thực sự, nó nên được gọi là "Con đường". Bên cạnh đó, nó có vẻ hoạt động và phù hợp với nhu cầu của dự án tốt và có thể sẽ đủ mở rộng trong nhiều năm tới. Vì cơ sở dữ liệu của bạn không bị đánh thuế và việc sắp xếp thực sự rất dễ dàng , nên sẽ tiếp tục như vậy trong nhiều năm tới.

Tôi sẽ không đổ mồ hôi.


Tôi không có vấn đề gì với phía khách hàng, khi tôi đi theo con đường đó với các ứng dụng Windows. Nhưng những gì về ứng dụng web? Tôi không tìm thấy bất kỳ giải pháp JavaScript nào thực sự đủ linh hoạt. Và vâng, nó hoạt động như tôi đã nói theo cách chúng ta có, nhưng đó là cơn ác mộng của SQL. Tất nhiên tôi muốn biết nếu có những cách tốt hơn.
Sean Hanley

Nó được tích hợp vào các điều khiển .NET mới hơn (2.0 trở lên). Hoặc bạn có thể tạo riêng của mình và áp dụng nó cho một dataview. msdn.microsoft.com/en-us/l Library / hwf94875 (VS.80) .aspx
DS

2
Vấn đề của tôi sau đó là một trong những khả năng mở rộng và hiệu suất. Thực hiện sắp xếp phía máy khách hoặc máy chủ web yêu cầu tải tất cả dữ liệu thay vì chỉ 10 hoặc 15 bạn sẽ hiển thị trên một trang mỗi lần. Điều này cực kỳ tốn kém, về lâu dài, trong khi sắp xếp cơ sở dữ liệu không có điều đó.
Sean Hanley

2

Khi bạn phân trang kết quả được sắp xếp, SQL động là một lựa chọn tốt. Nếu bạn hoang tưởng về việc tiêm SQL, bạn có thể sử dụng số cột thay vì tên cột. Tôi đã làm điều này trước khi sử dụng các giá trị âm cho giảm dần. Một cái gì đó như thế này ...

declare @o int;
set @o = -1;

declare @sql nvarchar(2000);
set @sql = N'select * from table order by ' + 
    cast(abs(@o) as varchar) + case when @o < 0 then ' desc' else ' asc' end + ';'

exec sp_executesql @sql

Sau đó, bạn chỉ cần đảm bảo số nằm trong khoảng 1 đến # cột. Bạn thậm chí có thể mở rộng nó thành một danh sách các số cột và phân tích nó thành một bảng số nguyên bằng cách sử dụng một hàm như thế này . Sau đó, bạn sẽ xây dựng thứ tự theo mệnh đề như vậy ...

declare @cols varchar(100);
set @cols = '1 -2 3 6';

declare @order_by varchar(200)

select @order_by = isnull(@order_by + ', ', '') + 
        cast(abs(number) as varchar) + 
        case when number < 0 then ' desc' else '' end
from dbo.iter_intlist_to_tbl(@cols) order by listpos

print @order_by

Một nhược điểm là bạn phải nhớ thứ tự của mỗi cột ở phía máy khách. Đặc biệt, khi bạn không hiển thị tất cả các cột hoặc bạn hiển thị chúng theo thứ tự khác. Khi khách hàng muốn sắp xếp, bạn ánh xạ tên cột theo thứ tự cột và tạo danh sách các số nguyên.


Chúng tôi sử dụng sp_executesql để xây dựng các truy vấn báo cáo động. Rất hiệu quả. SQL không thể được xây dựng từ ứng dụng, nhưng các tham số chỉ được chèn vào nơi cần thiết và thực thi như bình thường.
Josh Smeaton

2

Một đối số chống lại việc sắp xếp ở phía máy khách là dữ liệu khối lượng lớn và phân trang. Khi số lượng hàng của bạn vượt quá mức bạn có thể dễ dàng hiển thị, bạn thường sắp xếp như một phần của bỏ qua / mất, mà bạn có thể muốn chạy trong SQL.

Đối với Entity Framework, bạn có thể sử dụng một quy trình được lưu trữ để xử lý tìm kiếm văn bản của mình. Nếu bạn gặp phải vấn đề sắp xếp tương tự, giải pháp tôi đã thấy là sử dụng một Proc được lưu trữ cho tìm kiếm, chỉ trả về một khóa id được đặt cho khớp. Tiếp theo, truy vấn lại (với sắp xếp) đối với db bằng cách sử dụng id trong danh sách (chứa). EF xử lý việc này khá tốt, ngay cả khi bộ ID khá lớn. Vâng, đây là hai chuyến đi khứ hồi, nhưng nó cho phép bạn luôn luôn sắp xếp trong DB, điều này có thể quan trọng trong một số tình huống và ngăn bạn viết một lô logic trong thủ tục được lưu trữ.


1

Làm thế nào về việc xử lý sắp xếp trên các công cụ hiển thị kết quả - lưới, báo cáo, v.v. chứ không phải trên SQL?

BIÊN TẬP:

Để làm rõ mọi thứ vì câu trả lời này đã được bỏ phiếu trước đó, tôi sẽ giải thích một chút ...

Bạn nói rằng bạn biết về sắp xếp phía khách hàng nhưng muốn tránh xa nó. Đó là cuộc gọi của bạn, tất nhiên.

Tuy nhiên, điều tôi muốn chỉ ra là bằng cách thực hiện nó ở phía máy khách, bạn có thể kéo dữ liệu ONCE và sau đó làm việc với nó theo cách bạn muốn - so với thực hiện nhiều chuyến đi tới máy chủ mỗi lần sắp xếp được thay đổi.

Máy chủ SQL của bạn không bị đánh thuế ngay bây giờ và điều đó thật tuyệt vời. Không nên như vậy. Nhưng chỉ vì nó không bị quá tải nhưng không có nghĩa là nó sẽ tồn tại như vậy mãi mãi.

Nếu bạn đang sử dụng bất kỳ nội dung ASP.NET mới hơn nào để hiển thị trên web, rất nhiều nội dung đó đã được đưa vào ngay.

Có đáng để thêm rất nhiều mã vào mỗi thủ tục được lưu trữ chỉ để xử lý sắp xếp không? Một lần nữa, cuộc gọi của bạn.

Tôi không phải là người cuối cùng sẽ chịu trách nhiệm hỗ trợ nó. Nhưng hãy suy nghĩ về những gì sẽ liên quan khi các cột được thêm / xóa trong các bộ dữ liệu khác nhau được sử dụng bởi các thủ tục được lưu trữ (yêu cầu sửa đổi các câu lệnh CASE) hoặc khi đột nhiên thay vì sắp xếp theo hai cột, người dùng quyết định họ cần ba - yêu cầu bạn cập nhật mọi thủ tục được lưu trữ bằng phương pháp này.

Đối với tôi, thật đáng để có được một giải pháp phía khách hàng đang hoạt động và áp dụng nó cho một số màn hình hiển thị dữ liệu hướng tới người dùng và được thực hiện với nó. Nếu một cột mới được thêm vào, nó đã được xử lý. Nếu người dùng muốn sắp xếp theo nhiều cột, họ có thể sắp xếp theo hai hoặc hai mươi cột.


Đó sẽ là cách đúng đắn, nhưng không được coi là "cách tốt hơn"
DS

Bởi vì sau đó tôi vẫn đang viết cách sắp xếp của riêng mình bằng C # hoặc JavaScript và có vẻ như nó sẽ dễ dàng hơn và nhanh hơn rất nhiều trong SQL. Vì vậy, câu hỏi của tôi. Có phải tôi đã bỏ lỡ điều gì đó rõ ràng hoặc chúng tôi bị mắc kẹt khi viết cách sắp xếp tùy chỉnh của riêng mình (bằng C # hoặc JavaScript) mỗi ứng dụng chết tiệt mà chúng tôi làm việc?
Sean Hanley

3
Đợi đã, còn bộ kết quả với hàng chục ngàn hàng thì sao? Bạn không thể trả lại tất cả dữ liệu đó cho khách hàng. Bạn phải phân trang và sắp xếp trên cơ sở dữ liệu.
Râu Eric Z

Yadyn, đã hiểu. Nhưng một khi bạn có một bộ sắp xếp chung cho lưới của bạn, bạn chỉ cần sử dụng nó cho tất cả các công cụ của bạn.
Kevin Fairchild

Eric, Đúng ... Trong những trường hợp như vậy, bạn cần xử lý thêm và có thể nó sẽ có ý nghĩa trong SQL. Đó là một vấn đề đúng so với sai. Trong một số trường hợp, nó sẽ có ý nghĩa đối với SQL và một số trường hợp, trên máy khách.
Kevin Fairchild

1

Xin lỗi tôi đến bữa tiệc muộn, nhưng đây là một tùy chọn khác cho những người thực sự muốn tránh SQL động, nhưng muốn sự linh hoạt mà nó mang lại:

Thay vì tự động tạo SQL một cách nhanh chóng, hãy viết mã để tạo một Proc duy nhất cho mọi biến thể có thể. Sau đó, bạn có thể viết một phương thức trong mã để xem xét các tùy chọn tìm kiếm và yêu cầu nó chọn Proc phù hợp để gọi.

Nếu bạn chỉ có một vài biến thể thì bạn chỉ có thể tạo procs bằng tay. Nhưng nếu bạn có rất nhiều biến thể thì thay vì phải duy trì tất cả chúng, bạn chỉ cần duy trì trình tạo Proc thay vì để nó tạo lại chúng.

Là một lợi ích bổ sung, bạn sẽ nhận được các gói SQL tốt hơn để thực hiện tốt hơn theo cách này.


-1

Giải pháp này có thể chỉ hoạt động trong .NET, tôi không biết.

Tôi tìm nạp dữ liệu vào C # theo thứ tự sắp xếp ban đầu theo thứ tự SQL theo mệnh đề, đặt dữ liệu đó vào DataView, lưu trữ dữ liệu vào biến Phiên và sử dụng dữ liệu đó để xây dựng trang.

Khi người dùng nhấp vào tiêu đề cột để sắp xếp (hoặc trang hoặc bộ lọc), tôi không quay lại cơ sở dữ liệu. Thay vào đó, tôi quay trở lại DataView được lưu trong bộ nhớ cache của mình và đặt thuộc tính "Sắp xếp" của nó thành một biểu thức tôi xây dựng động, giống như tôi sẽ tạo SQL động. (Tôi thực hiện lọc theo cách tương tự, sử dụng thuộc tính "RowFilter").

Bạn có thể thấy / cảm thấy nó hoạt động trong bản demo của ứng dụng của tôi, BugTracker.NET, tại địa chỉ http: //ifdained.com/btnet/bugs.aspx


NGỌT! Bug tracker.NET đá!
digiguru

-7

Bạn nên tránh sắp xếp SQL Server, trừ khi cần thiết. Tại sao không sắp xếp trên máy chủ ứng dụng hoặc phía khách hàng? Ngoài ra .NET Generics không có sortin đặc biệt


6
Vì khả năng mở rộng. Sẽ tốt cho vài nghìn hàng, nhưng tôi không muốn kéo xuống mười nghìn và sắp xếp thứ đó. Hoặc hơn. Ngoài ra, những gì về phân trang? Tôi thường chỉ muốn kéo theo những gì tôi cần hiển thị. Sắp xếp các hàng 21-30 của 24056 sau khi thực tế sẽ không chính xác.
Sean Hanley
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.