2013-02-26 23 views
5

Tworzę poniżej procedurę składowaną.Przekazywanie kolejności dynamicznej według procedury składowanej

declare @PageNum as Int 
declare @PerPageResult as Int 
declare @StartDate as varchar(25) 
declare @EndDate as varchar(25) 
declare @SortType as Varchar(50) 
declare @SortDirection as Varchar(4) 
set @PageNum=1 
set @PerPageResult=20 
set @StartDate='2008-02-08' 
set @EndDate='2015-02-08' 
set @SortType='RegDate' 
set @SortDirection='Desc' 
declare @Temp Table(RowNum int, RegDate Date, Registered int, Female int, Male int, [Join] int, Rebill int, TotalPointsEarned int, Expire int) 
declare @sort varchar(50) 
Insert into @Temp 
    Select ROW_NUMBER() over (order by @SortType+' '[email protected]) As RowNum, * From ( 
    SELECT 
    CAST(m.registrationdate AS Date) as RegDate,  
    count(m.id) Registered, 
    count(CASE WHEN m.gender='F' then 'F' end) As Female, 
    count(CASE WHEN m.gender='M' then 'M' end) As Male 
    count(CASE WHEN p.paymenttransactiontype='N' then 'N' end) As [Join], 
    count(CASE WHEN p.paymenttransactiontype='R' then 'R' end) As Rebill, 
    count(m.tokensearned) As TotalPointsEarned, 
    count(CASE WHEN p.paymenttransactiontype='E' then 'E' end) As Expire 
    from member m 
    join payment p on m.id=p.id_member 
    join user_role u on u.member_id=m.id 
    where u.role_id <> 3 
    and CAST(m.registrationdate AS Date) > @StartDate and CAST(m.registrationdate AS Date) < @EndDate 
    GROUP BY CAST(m.registrationdate AS Date) 
    ) as aa 
    Select * from @Temp Where RowNum>((@PageNum-1)*@PerPageResult) and RowNum<[email protected] * @PageNum 
    Order by @SortType+' '[email protected] 

W wyżej kiedy mijam klauzuli Order by dynamicznie, to nie sortowania danych poprawnie, ale kiedy piszę Nazwa kolumny wyraźnie, że działa dobrze. Może być jej podjęcia @SortType+' '[email protected] jak varchar zamiast Date

Próbowałem pisać Order by case when (@Sort='RegDate' and @SortDirection='Desc') Then RegDate End Desc, ale to nie działa

Jak mogę przekazać zamówienie dynamicznie tutaj.

Edycja: @Andomar: Próbowałem dostarczonego rozwiązania i dodano jeszcze jedno pole dla typu Date. I to też nie zadziałało.

poniżej to, co zrobiłem.

create table t1 (id int, name varchar(50), dt date); 
insert t1 values 
    (1, 'Chihiro Ogino','2009-02-08'), 
    (2, 'Spirit of the Kohaku River','2008-02-08'), 
    (3, 'Yubaba','2012-02-08'); 



declare @sortColumn varchar(50) = 'dt' 
declare @sortOrder varchar(50) = 'ASC' 

select * 
from t1 
order by 
     case 
     when @sortOrder <> 'ASC' then 0 
     when @sortColumn = 'id' then id 
     end ASC 
,  case 
     when @sortOrder <> 'ASC' then '' 
     when @sortColumn = 'name' then name 
     end ASC 
,  case 
     when @sortOrder <> 'ASC' then '' 
     when @sortColumn = 'dt' then name 
     end ASC 
,  case 
     when @sortOrder <> 'DESC' then 0 
     when @sortColumn = 'id' then id 
     end DESC 
,  case 
     when @sortOrder <> 'DESC' then '' 
     when @sortColumn = 'name' then name 
     end DESC 
,  case 
     when @sortOrder <> 'DESC' then '' 
     when @sortColumn = 'dt' then name 
     end DESC 
+0

gender = 'SH': Nie widziałem, że przed ... –

+0

@MitchWheat: Zignoruj: P –

+0

wyszukaj "ORDER BY CASE" –

Odpowiedz

13

Można użyć skomplikowanego order by klauzuli. To wymaga jednego case dla każdego kierunku sortowania i każdego rodzaju danych. Z tym przykładowym zbiorze:

create table t1 (id int, name varchar(50), created date); 
insert t1 values 
    (1, 'Chihiro Ogino', '2012-01-01'), 
    (2, 'Spirit of the Kohaku River', '2012-01-03'), 
    (3, 'Yubaba', '2012-01-02'); 

Można użyć order by klauzuli takiego:

declare @sortColumn varchar(50) = 'created' 
declare @sortOrder varchar(50) = 'DESC' 

select * 
from t1 
order by 
     case 
     when @sortOrder <> 'ASC' then 0 
     when @sortColumn = 'id' then id 
     end ASC 
,  case 
     when @sortOrder <> 'ASC' then '' 
     when @sortColumn = 'name' then name 
     end ASC 
,  case 
     when @sortOrder <> 'ASC' then cast(null as date) 
     when @sortColumn = 'created' then created 
     end ASC 
,  case 
     when @sortOrder <> 'DESC' then 0 
     when @sortColumn = 'id' then id 
     end DESC 
,  case 
     when @sortOrder <> 'DESC' then '' 
     when @sortColumn = 'name' then name 
     end DESC 
,  case 
     when @sortOrder <> 'DESC' then cast(null as date) 
     when @sortColumn = 'created' then created 
     end DESC 

Working example at SQL Fiddle.

Inną opcją jest stworzenie dynamicznie kwerendy i uruchomić go z exec. Na przykład:

declare @sql nvarchar(max) 
set @sql = 'select * from YourTable order by ' + @sortColumn + ' ' + @sortDir 
exec (@sql) 
+0

zamiast przypadku, mamy lepsze rozwiązanie, ponieważ mam 11 kolumn do sortowania. –

+0

Próbowałem pisać porządek przez przypadek, gdy (@ Sort = "RegDate" i @ SortDirection = "Desc") Następnie RegDate End Desc, ale to nie zadziałało –

+0

@JitendraPancholi: To powinno działać, jeśli zmienne są ustawione poprawnie. – Andomar

-2

coś jak to powinno działać:

ORDER BY 
    CASE WHEN @SortDirection = 'ASC' THEN @SortType END ASC, 
    CASE WHEN @SortDirection = 'DESC' THEN @SortType END DESC 
+0

Zamawianie według 'SortType' nie będzie działać. SQL Server nie zezwala na zmienną w miejsce nazwy kolumny. – Andomar

+0

zamiast przypadku, mamy lepsze rozwiązanie, ponieważ mam 11 kolumn do sortowania. –

+0

@Andomar Nie, serwer Sql 2008 r2 akceptuje to, po prostu próbowałem (zapomnij najpierw umieścić @ pod pierwszym imieniem) –

0

@ Odpowiedź Andomara pomaga rozwiązać podobny problem. Musiałem posortować dowolną liczbę 23 różnych kolumn w dowolnej kolejności. Skończyło się, co następuje:

create table sorting(ID int, columnName varchar(50), sort varchar(10), position int) 
insert into sorting 
values(1,'column1','DESC',1), 
     (1,'column2','ASC',2), 
     ...    
     (1,'columnN','DESC',N) 

Dodanie parametru @sort do SP zidentyfikować wpisów Sortowanie:

ORDER BY ISNULL(STUFF((SELECT ', ' + a.columnName + ' ' + a.sort 
        FROM sorting a 
        WHERE a.ID = @sort 
        ORDER BY a.position ASC 
      FOR XML PATH('')), 1, 2, ''),NULL) 
0

Istnieją dwa podstawowe podejścia do budowania procedur przechowywanych dynamicznie można zamówić:

  1. Przeprowadź klauzulę ORDER BY jako parametr do procedury składowanej. W procedurze przechowywanej zbuduj instrukcję SQL w łańcuchu, a następnie wykonaj tę instrukcję, używając EXEC lub sp_ExecuteSql.

    -- This Method is used when your Column names are dynamic 
    -- We need to create a dynamic query and Execute it as shown below. 
    
    CREATE PROCEDURE getEmployees (@OrderByClause varchar(100)) AS 
    
    -- Create a variable @SQLStatement 
    DECLARE @SQLStatement varchar(255) 
    
    -- Enter the dynamic SQL statement into the 
    -- variable @SQLStatement 
    SELECT @SQLStatement = 'SELECT EmployeeID, FirstName, LastName, SSN, Salary 
    FROM Employees ORDER BY '+ @OrderByClause+'' 
    
    -- Execute the SQL statement 
    EXEC(@SQLStatement) 
    
  2. przejściu w kolumnie, a następnie posortować przez użycie CASE komunikatu w klauzuli ORDER BY zamówić wyniki w zależności od wartości parametru wejściowego.

    --This method is used when you column name is not dynamic 
    
    SELECT EmployeeID, FirstName, LastName, SSN, Salary 
    FROM Employees 
    ORDER BY 
        CASE WHEN @ColumnName='LastName' THEN LastName 
         WHEN @ColumnName='Salary' THEN CONVERT(varchar(50), Salary) 
         WHEN @ColumnName='SSN' THEN SSN 
        END 
    
Powiązane problemy