Avatar billede linebille Nybegynder
18. marts 2004 - 13:14 Der er 47 kommentarer og
1 løsning

sql syntax order by

jeg har en procedure der selecter en masse rækker. Jeg vil vælge hvad den skal 'orders by' ved hjælp af et inputparameter og noget IF sætning, men hvordan er syntaksen?

CREATE PROCEDURE getBugs2 @ProjectID integer, @sort_item varchar(10)
AS
SELECT (en hel masse rækker...)
FROM (en hel masse tabeller)
WHERE (en hel masse betingelser)

og så hvad??? måske sådan noget?:

IF @sort_item = 'dateSort'
    ORDER BY BugReportDate DESC
IF @sort_item = 'customerSort'
    ORDER BY CustomerFirstName
IF @sort_item = 'bugtypeSort'
    ORDER BY BugTypeDescription
IF @sort_item = 'bugstatusSort'
    ORDER BY BugReportDate DESC
Avatar billede krydset Nybegynder
18. marts 2004 - 13:16 #1
SELECT (en hel masse rækker...)
FROM (en hel masse tabeller)
WHERE (en hel masse betingelser)
ORDER BY (en betingelse)

Tror jeg
Avatar billede venne Nybegynder
18. marts 2004 - 13:20 #2
Du kan ikke have IF inde midt i SELECT, men dette burde virke:

CREATE PROCEDURE getBugs2 @ProjectID integer, @sort_item varchar(10)
AS

IF @sort_item = 'dateSort'

SELECT (en hel masse rækker...)
FROM (en hel masse tabeller)
WHERE (en hel masse betingelser)
ORDER BY BugReportDate DESC

ELSE IF @sort_item = 'customerSort'

SELECT (en hel masse rækker...)
FROM (en hel masse tabeller)
WHERE (en hel masse betingelser)
ORDER BY CustomerFirstName

ELSE IF ...

osv...
Avatar billede linebille Nybegynder
18. marts 2004 - 13:20 #3
hvad mener du?

kan du gi et eksempel?
Avatar billede linebille Nybegynder
18. marts 2004 - 13:21 #4
>>venne det lyder ok jeg prøver det lige..
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:22 #5
Så skal du være opmærksom på, at du skal have en if-betingelse med fuldt select for hver sorteringsmulighed.
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:25 #6
En anden mulighed er at bruge case


CREATE PROCEDURE getBugs2 @ProjectID integer, @sort_item varchar(10)
AS
SELECT (en hel masse rækker...)
FROM (en hel masse tabeller)
WHERE (en hel masse betingelser)
order by case
          when @sort_item = 'dateSort' then <date-feltets nummer i select>
          when @sort_item = 'customerSort' then <customer-feltets nummer i select>
          else <default-sorteringsfeltets nummer i select>
        end


Du kan ikke bare bruge feltnavnet, da du har forskellige felttyper, og der forsøges konvertering til fælles datatype, hvilket ofte vil blive int.
Avatar billede linebille Nybegynder
18. marts 2004 - 13:30 #7
>>bennytordrup
det ser jo pænere ud, så får jeg heller ikke den temmelig store mængde gentagen kode når jeg selecter - jeg prøver lige..
Avatar billede linebille Nybegynder
18. marts 2004 - 13:33 #8
Jeg selecter dette her, er <date-feltets nummer i select> så 1 eller 2 eller hvad er det for noget?


SELECT  tblBugs.BugID,
    tblBugs.BugReportDate,
    tblBugTypes.BugTypeDescription,
    tblBugs.BugDescription,
    BugDescReply = case when BugDescReply is Null Then '' Else BugDescReply End ,
    tblCustomers.CustomerFirstName,
    tblCustomers.CustomerLastName,
    tblCustomers.CustomerEmail1,
    tblDepartments.DepartmentName,
    tblCompanies.CompanyName,
    CompanyWWW= case when CompanyWWW is Null Then '' Else CompanyWWW End ,--isnull(companywww,'') as companywwww
    tblBugStatus.BugStatusDescription,
    tblBugHandlers.BugHandlerFirstName,
    tblBugHandlers.BugHandlerLastName,
    tblBugHandlers.BugHandlerEmail
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:35 #9
tblBugs.BugReportDate er felt 2
tblCustomers.CustomerFirstName er felt 6
Avatar billede linebille Nybegynder
18. marts 2004 - 13:36 #10
når jeg skriver:

ORDER BY CASE when @sort_item = 'dateSort' then 2
              when @sort_item = 'customerSort' then 6
              else 2
          end

Server: Msg 1008, Level 15, State 1, Procedure getBugs2, Line 38
The SELECT item identified by the ORDER BY number 1 contains a variable as part of the expression identifying a column position. Variables are only allowed when ordering by an expression referencing a column name.
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:39 #11
Prøv at udkommentere linien

bugsdescreply = case ...

og lav 6-tallet om til et 5-tal i order by
Avatar billede linebille Nybegynder
18. marts 2004 - 13:42 #12
gjort + jeg udkommenterede linien

CompanyWWW= case

samme fejl:
Server: Msg 1008, Level 15, State 1, Procedure getBugs2, Line 38
The SELECT item identified by the ORDER BY number 1 contains a variable as part of the expression identifying a column position. Variables are only allowed when ordering by an expression referencing a column name.
Avatar billede linebille Nybegynder
18. marts 2004 - 13:48 #13
men det her virker :-) HURRA!

ORDER BY CASE when @sort_item = 'dateSort' then BugReportDate
              when @sort_item = 'customerSort' then CustomerFirstName
              else BugReportDate
          end
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:49 #14
Hvad felttyper arbejder du med?
Avatar billede linebille Nybegynder
18. marts 2004 - 13:56 #15
en dato - en smalldate er det vist - og nogle varchars
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 13:59 #16
Så er det spørgsmålet, om dato-sortering bliver korrekt.
Avatar billede linebille Nybegynder
18. marts 2004 - 14:03 #17
ok jeg var lidt hurtig til at juble..

på datoen fungerer det fint, tilsyneladende også på den ene varchar (CustomerFirstName)
men ikke når jeg sorterer på BugTypeDescription eller BugStatusDescription
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:04 #18
Hvad felttyper er det?
Avatar billede linebille Nybegynder
18. marts 2004 - 14:08 #19
varchar's
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:09 #20
Hvad går der galt?
Avatar billede linebille Nybegynder
18. marts 2004 - 14:17 #21
jeg ved det ikke
jeg smider lige hele proceduren som den ser ud nu:

if exists (select * from dbo.sysobjects where id = object_id(N'[azomian].[getBugs2]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE getBugs2
GO
CREATE PROCEDURE getBugs2 @ProjectID integer, @sort_item varchar(10)

AS

SELECT  tblBugs.BugID,
    tblBugs.BugReportDate,
    tblBugTypes.BugTypeDescription,
    tblBugs.BugDescription,
    BugDescReply = case when BugDescReply is Null Then '' Else BugDescReply End ,
    tblCustomers.CustomerFirstName,
    tblCustomers.CustomerLastName,
    tblCustomers.CustomerEmail1,
    tblDepartments.DepartmentName,
    tblCompanies.CompanyName,
    CompanyWWW= case when CompanyWWW is Null Then '' Else CompanyWWW End ,--isnull(companywww,'') as companywwww
    tblBugStatus.BugStatusDescription,
    tblBugHandlers.BugHandlerFirstName,
    tblBugHandlers.BugHandlerLastName,
    tblBugHandlers.BugHandlerEmail
FROM    tblBugs,
    tblBugTypes,
    tblCustomers,
    tblDepartments,
    tblCompanies,
    tblBugStatus,
    tblBugHandlers
WHERE    tblBugs.ProjectID=@ProjectID
    AND tblBugs.BugTypeID=tblBugTypes.BugTypeID
    AND tblBugs.CustomerID=tblCustomers.CustomerID
    AND tblCustomers.DepartmentID=tblDepartments.DepartmentID
    AND tblDepartments.CompanyID=tblCompanies.CompanyID
    AND tblBugs.BugStatusID=tblBugStatus.BugStatusID
    AND tblBugs.BugHandlerID=tblBugHandlers.BugHandlerID

ORDER BY CASE when @sort_item = 'dateSort' then BugReportDate
                                                                    --smalldate
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
                                                                    --varchar
          when @sort_item = 'bugTypeSort' then BugTypeDescription
                                                                    --varchar
          when @sort_item = 'bugStatusSort' then  BugStatusDescription 
                                                                    --varchar
              else BugReportDate
          end
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:19 #22
Er det resultatet, som er forkert, eller hvad?
Avatar billede linebille Nybegynder
18. marts 2004 - 14:24 #23
ja det er når jeg kalder proceduren med

exec getBugs2 1, bugStatusSort

får jeg de forventede rækker, bare ikke sorteret efter BugStatusDescription
Avatar billede linebille Nybegynder
18. marts 2004 - 14:24 #24
ligesådan hvis jeg kalder

exec getBugs2 1, bugTypeSort
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:25 #25
prøv

exec getBugs2 1, 'bugTypeSort'
Avatar billede linebille Nybegynder
18. marts 2004 - 14:26 #26
men når jeg kalder
exec getBugs2 1, dateSort
eller
exec getBugs2 1, customerSort

virker det tilsyneladende fint ... lidt underligt ..
Avatar billede linebille Nybegynder
18. marts 2004 - 14:27 #27
exec getBugs2 1, 'bugTypeSort'

giver det samme
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:31 #28
Prøv at lave et create script af tblCustomers, tblBugTypes, tblBugStatus og tblBugs
Avatar billede linebille Nybegynder
18. marts 2004 - 14:38 #29
efter lidt mere test kan jeg se at customerSort heller ikke virker, ej heller dateSort egentlig..øvøv

men jeg kan godt pille select sætningen ud og sige order by f.eks BugStatusDescription i query analyzeren og få det rigtigt sorteret

hvad mener du med at "lave" et create script vil du se dem?
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:40 #30
Prøv at ændre Order By til følgende:

ORDER BY CASE when @sort_item = 'dateSort' then convert(varchar(8), BugReportDate, 112)
                                                                    --smalldate
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
                                                                    --varchar
          when @sort_item = 'bugTypeSort' then BugTypeDescription
                                                                    --varchar
          when @sort_item = 'bugStatusSort' then  BugStatusDescription 
                                                                    --varchar
              else BugReportDate
          end
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:41 #31
Det, jeg gør her, er at caste datoen til en varchar med formatet yyyymmdd. Derved kan den datosortere som en streng (og dermed samme felttype som de øvrige).
Avatar billede linebille Nybegynder
18. marts 2004 - 14:46 #32
prøvet - samme resultat - intet virker
Avatar billede linebille Nybegynder
18. marts 2004 - 14:53 #33
det må være casen der ikke funker...
Avatar billede venne Nybegynder
18. marts 2004 - 14:56 #34
Jeg indskyder lige en bemærkning: @sort_item er defineret som varchar(10), det er ikke nok til de parametre du kalder med.
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 14:57 #35
Prøv at ændre din parameterdefinition

@sort_item varchar(50)

Det er kun dateSort, der er mindre end 10 tegn, så du får altid sorteret efter datoen.
Avatar billede linebille Nybegynder
18. marts 2004 - 14:57 #36
--for hvis jeg i query analyzer skriver:

SELECT  tblBugs.BugID,
    tblBugs.BugReportDate,
    tblBugTypes.BugTypeDescription,
    tblBugs.BugDescription,
    BugDescReply = case when BugDescReply is Null Then '' Else BugDescReply End ,
    tblCustomers.CustomerFirstName,
    tblCustomers.CustomerLastName,
    tblCustomers.CustomerEmail1,
    tblDepartments.DepartmentName,
    tblCompanies.CompanyName,
    CompanyWWW= case when CompanyWWW is Null Then '' Else CompanyWWW End ,--isnull(companywww,'') as companywwww
    tblBugStatus.BugStatusDescription,
    tblBugHandlers.BugHandlerFirstName,
    tblBugHandlers.BugHandlerLastName,
    tblBugHandlers.BugHandlerEmail
FROM    tblBugs,
    tblBugTypes,
    tblCustomers,
    tblDepartments,
    tblCompanies,
    tblBugStatus,
    tblBugHandlers
WHERE    tblBugs.ProjectID=1
    AND tblBugs.BugTypeID=tblBugTypes.BugTypeID
    AND tblBugs.CustomerID=tblCustomers.CustomerID
    AND tblCustomers.DepartmentID=tblDepartments.DepartmentID
    AND tblDepartments.CompanyID=tblCompanies.CompanyID
    AND tblBugs.BugStatusID=tblBugStatus.BugStatusID
    AND tblBugs.BugHandlerID=tblBugHandlers.BugHandlerID

ORDER BY BugTypeDescription

-fungerer det fint, men altså ikke via proceduren...
Avatar billede linebille Nybegynder
18. marts 2004 - 15:08 #37
:-) den med parameteren er ændret nu til varchar(50)

nu fungerer dateSort

men på customerSort får jeg

Server: Msg 295, Level 16, State 3, Procedure getBugs2, Line 5
Syntax error converting character string to smalldatetime data type.

så det må være noget mere konvertering der skal til?
Avatar billede linebille Nybegynder
18. marts 2004 - 15:11 #38
nu var jeg for hurtig igen...nej  datesort fungerer heller ikke - intet fungerer - men jeg får ingen fejlbeskeder når jeg kører datesort
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 15:14 #39
Har du sat den convert ind i casen, som jeg beskrev i indlægget dateret 18/03-2004 14:40:35?
Avatar billede linebille Nybegynder
18. marts 2004 - 15:22 #40
ja og ligenu har jeg også husket at have den med i else delen.
efter velovervejet test, denne gang, :-) er resultatet at fungerer, undtagen på datoen
Avatar billede linebille Nybegynder
18. marts 2004 - 15:29 #41
så prøvede jeg at fjerne convert fra casen og gå til bage til

ORDER BY CASE when @sort_item = 'dateSort' then BugReportDate
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
              when @sort_item = 'bugTypeSort' then BugTypeDescription
              when @sort_item = 'bugStatusSort' then  BugStatusDescription 
              else BugReportDate
              end

så bliver det omvendt, så fungerer

'customerSort', 'bugTypeSort' og 'bugStatusSort'

men ved exec getBugs2 2,customerSort fås:

Server: Msg 295, Level 16, State 3, Procedure getBugs2, Line 5
Syntax error converting character string to smalldatetime data type.
Avatar billede linebille Nybegynder
18. marts 2004 - 15:31 #42
SE BORT FRA FORRIGE KOMMENTAR, DET SKULLE HAVE VÆRET:

det gik lidt hurtigt

så prøvede jeg at fjerne convert fra casen og gå til bage til

ORDER BY CASE when @sort_item = 'dateSort' then BugReportDate
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
              when @sort_item = 'bugTypeSort' then BugTypeDescription
              when @sort_item = 'bugStatusSort' then  BugStatusDescription 
              else BugReportDate
              end

så bliver det omvendt, så fungerer

dateSort

men ved exec getBugs2 2,customerSort fås:

Server: Msg 295, Level 16, State 3, Procedure getBugs2, Line 5
Syntax error converting character string to smalldatetime data type.
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 15:32 #43
Prøv denne

ORDER BY CASE when @sort_item = 'dateSort' then convert(varchar(8), BugReportDate, 112)
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
              when @sort_item = 'bugTypeSort' then BugTypeDescription
              when @sort_item = 'bugStatusSort' then  BugStatusDescription 
              else convert(varchar(8), BugReportDate, 112)
              end
Avatar billede linebille Nybegynder
18. marts 2004 - 15:38 #44
ja den er jeg gået tilbage til igen og så virker     

'customerSort', 'bugTypeSort' og 'bugStatusSort'

men ikke

'dateSort'
Avatar billede linebille Nybegynder
18. marts 2004 - 15:45 #45
min testdata er rækker, hvor BugReportDate giver current_timestamp, dvs. datoen vil "ligge i samme kronologiske rækkefølge" som det ID rækken bliver givet. Derfor ville jeg ikke kunne se om dateSort egentlig fungerer. Derfor tester jeg det ved at sætte DESC og ASC efter ORDER BY delen, og med begge dele står datoen i samme rækkefølge, men så tænker jeg: måske virker den sådan set, men ASC og DESC kan ikke benyttes på tal? jeg ved godt datoen er konverteret til en varchar, men den indeholder jo stadig tal..? er det et vildskud?
Avatar billede linebille Nybegynder
18. marts 2004 - 15:57 #46
ja det var det der var!
ændrede lidt i mine testdata og kunne se at alt virkede.
Meget velfortjente point bennytordrup :-)
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 15:57 #47
prøv:

ORDER BY CASE when @sort_item = 'dateSort' then convert(varchar(25), BugReportDate, 121)
              when @sort_item = 'customerSort' then tblCustomers.CustomerLastName
              when @sort_item = 'bugTypeSort' then BugTypeDescription
              when @sort_item = 'bugStatusSort' then  BugStatusDescription 
              else convert(varchar(25), BugReportDate, 121)
              end


Desuden ændrer du i select:

SELECT  tblBugs.BugID,
    convert(varchar(25), tblBugs.BugReportDate, 121),
    tblBugTypes.BugTypeDescription,
Avatar billede bennytordrup Nybegynder
18. marts 2004 - 15:58 #48
Takker.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester