webForumDet fria alternativet

sp Order By dynamiskt

12 svar · 222 visningar · startad av KalsongCesar

KalsongCesarMedlem sedan mars 2001338 inlägg
#1

har läst och hittat ngr svar här men de hjälpte inte mig.

Jag vill skicka med en variabel i min sp som styr vad som ska sorteras efter.
orginal

CREATE PROCEDURE spListUserPay2 
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY Users.expiryDate DESC
GO

nu har jag provat med att lägga till min variabel. men det går inte..

CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY @sort
GO

Kollade lite på en annan fråga som körde en select och vid vissa case casta om men det fick jag inte heller till..

Ngn som har lite tid över?

LarsGMedlem sedan dec. 200012 465 inlägg
#2

Eftersom du har distinct så kan du bara sortera på sådant som finns med i select-listan.

Om @sort innehåller kolumnnamn så:

CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad,
               case @sort when 'Title' then title
                                  when 'Name' then name end
                        as sort
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY sort
GO

Det går så länge alla kolumner som du vill sortera på är av samma datatyp.

KalsongCesarMedlem sedan mars 2001338 inlägg
#3

oki.. det verkar ju logiskt, men jag får inte ens skapa min sp det blir error 1008

LarsGMedlem sedan dec. 200012 465 inlägg
#4

1008 just det ja, jag förstår ... inte.

Vad är feltexten och hur ser proceduren ut?

KalsongCesarMedlem sedan mars 2001338 inlägg
#5

Error 1008: 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
=)

LarsGMedlem sedan dec. 200012 465 inlägg
#6
CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
select * from (
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL) s
ORDER BY case @sort when 'Title' then title
                                  when 'Name' then name end
KalsongCesarMedlem sedan mars 2001338 inlägg
#7

tack, jag provade din lösning, som jag även sett på ett annat fall här, åxå testat med cast för att få den till varchar men ingen förbättring. Det som händer nu är att den säger att fältet måste finnas med om distinct används.

LarsGMedlem sedan dec. 200012 465 inlägg
#8

Måste du ha distinct då?

KalsongCesarMedlem sedan mars 2001338 inlägg
#9

ja, jag väljer ut en person och dennes fakturor.. har den fler så vill jag inte få upp honnom flera ggr på listan.

LarsGMedlem sedan dec. 200012 465 inlägg
#10

oki, nytt förslag

if @sort = 'Title' 

SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL
order by title
else if @sort = 'Name' 
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL
order by name

Jag ändrade från = NULL till is NULL också.

Ett annat alternativ är att skapa en sträng som innehåller frågan

@declare str varchar(2000)
set @str = 'SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL order by ' + @sort
exec (@str)
KalsongCesarMedlem sedan mars 2001338 inlägg
#11

Ska testa pronto imorgon bitti.. tack, dags att dra iväg..

LarsGMedlem sedan dec. 200012 465 inlägg
#12

För att slippa distinct så borde du kunna byta ut någon av dina joinar mot en korrelerad subquery (Eftersom jag inte orkar göra en begåvad gissning om din tabellstruktur så gör jag ett generellt exempel.)

select distint t1.c1,t1.c2 from t1 inner join t2 on t1.id  = t2.id

kan bytas mot

select c1,c2 from t1
where exists (select * from t2 where id = t1.id)

som förmodligen är effektivare också.

KalsongCesarMedlem sedan mars 2001338 inlägg
#13

funkade fint att ha if satsen som kollade strängen.... nöjer med det så länge.. men vem vet, kanske kommer tillbaka till tråden snabbare än jag trott ;)

Genererad på 494 ms · cache AV · v20260730165559-full.f96bc7eb