اتجاه النظام الديناميكي
-
18-09-2019 - |
سؤال
أنا أكتب SP الذي يقبل عمود المعلمات للفرز والاتجاه.
لا أريد استخدام SQL الديناميكي.
تكمن المشكلة في تحديد معلمة الاتجاه.
هذا هو الكود الجزئي:
SET @OrderByColumn = 'AddedDate'
SET @OrderDirection = 1;
…
ORDER BY
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
المحلول
هل يمكن أن يكون لديك اثنين تقريبا متطابقة ORDER BY
البنود، واحد ASC
و واحد DESC
, ، وتوسيع الخاص بك CASE
بيان لجعل واحدة أو غيرها منهم يساوي دائما قيمة واحدة:
ORDER BY
CASE WHEN @OrderDirection = 0 THEN 1
ELSE
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
END ASC,
CASE WHEN @OrderDirection = 1 THEN 1
ELSE
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
END DESC
نصائح أخرى
يمكنك تبسيط الحال باستخدام Row_Number الذي يقوم بفرز بياناتك وتحويله بشكل فعال إلى تنسيق صحيح سهل الاستخدام. خاصة وأن السؤال هو الموسومة SQL Server 2005
هذا يتوسع أيضا بسهولة كافية للتعامل مع أنواع الثانوية والثالث
لقد استخدمت المضاعف لتبسيط عبارة SELECT الفعلية مرة أخرى وتقليل فرصة تقييم RBAR بالترتيب حسب
DECLARE @multiplier int;
SELECT @multiplier = CASE @Direction WHEN 1 THEN -1 ELSE 1 END;
SELECT
Columns you actually want
FROM
(
SELECT
Columns you actually want,
ROW_NUMBER() OVER (ORDER BY AddedDate) AS AddedDateSort,
ROW_NUMBER() OVER (ORDER BY Visible) AS VisibleSort,
ROW_NUMBER() OVER (ORDER BY AddedBy) AS AddedBySort,
ROW_NUMBER() OVER (ORDER BY Title) AS TitleSort
FROM
myTable
WHERE
MyFilters...
) foo
ORDER BY
CASE @OrderByColumn
WHEN 'AddedDate' THEN AddedDateSort
WHEN 'Visible' THEN VisibleSort
WHEN 'AddedBy' THEN AddedBySort
WHEN 'Title' THEN TitleSort
END * @multiplier;
هنا مثال:
CREATE PROCEDURE GetProducts
(
@OrderBy VARCHAR(50),
@Input2 VARCHAR(30)
)
AS
BEGIN
SET NOCOUNT ON
SELECT Id, ProductName, Description, Price, Quantity
FROM Products
WHERE ProductName LIKE @Input2
ORDER BY
CASE
WHEN @OrderBy = 'ProductNameAsc' THEN ProductName
END ASC,
CASE
WHEN @OrderBy = 'ProductNameDesc' THEN ProductName
END DESC
END
من هنا:
http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql
يجب تجميع الإجراءات الصعودية والهبوط في بيانات حالة منفصلة ، مفصولة بفاصلة.في الرمز/البرنامج النصي من جانب الخادم ، تأكد من إلحاق "ASC" أو "DESC" بالترتيب حسب السلسلة ، أو قد يكون لديك معلمات إدخال الإجراء المخزنة لاسم العمود والطلب حسب الاتجاه إذا كنت تريد.
هذا يفي بالغرض بالنسبة لي - (where
, order by
, direction
,Pagination
)
parameters
@orderColumn int ,
@orderDir varchar(20),
@start int ,
@limit int
select * from items
WHERE (items.status = 1)
order by
CASE WHEN @orderColumn = 0 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 0 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'asc' THEN items.[category] END ASC
OFFSET @start ROWS FETCH NEXT @limit ROWS ONLY
نسخة أكثر ضغط من المقبول إجابه, ولكن كما هو مقبول الإجابة هذا يعمل بشكل جيد فقط عند التعبيرات الناتجية بعد THEN
لديك نفس النوع.
ORDER BY
CASE @OrderDirection WHEN 0 THEN
CASE @sortColumn
WHEN 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN 'AddedBy' THEN AddedBy
WHEN 'Title' THEN Title
END
END ASC,
CASE @OrderDirection WHEN 1 THEN
CASE @sortColumn
WHEN 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN 'AddedBy' THEN AddedBy
WHEN 'Title' THEN Title
END
END DESC