[ASP/SQL] Records schuiven dmv Up/Down knop

Pagina: 1
Acties:
  • 191 views sinds 30-01-2008
  • Reageer

  • Polderdijk
  • Registratie: December 2001
  • Laatst online: 19-05 14:10
Misschien een beetje vage topictitel maar ik kan het niet anders omschrijven :|

Maar ik ben bezig met een stukje scripting waarmee ik me partner-database van me website in kan beheren. Nu is dit ipc niet zo moeilijk als je het zo maakt dat bijvoorbeeld elke nieuwe partner gewoon onder aan de lijst aanschuift.

Maar dat wil ik dus niet. Ik wil dus nieuwe records in het tabel Parterns kunnen zetten, maar ik wil ook dat ik kan 'schuiven' met de records. Zodat ik bijvoorbeeld het 4e record uit de lijst bovenaan zet.

Nu had ik in gedachte om een extra kolom 'Ranking' aan te maken en daarin dmv cijfers de volgorde bepalen en met het tonen van de lijst dat ik dan sorteer op het veld Ranking.

Maar ik ben benieuwd hoe ik dit moet programmeren, ik geloof dat ik weer eens veel te moeilijk zit te denken en dat er een makkelijkere oplossing is, toch :?

Dus ik wil in een adminpagina bij elk record een Up en Down knop hebben, en als ik er dan op klikt dat het huidige record dus één plaats omhoog, of naar beneden gaat.

Ik hoef geen programmeervoorbeelden te hebben, wel zou het fijn zijn om hier een duidelijke beredenering te geven waarna ik het kan programmeren :)

Webhosting van SkyHost.nl: 25 Mb / 1 Gb windows hosting € 4,50 p/m excl.btw!


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
De positie waarin je records in de tabel zitten is van geen belang. Je moet ze er gewoon in de gewenste volgorde uithalen (ORDER BY)

Je kunt misschien een veldje 'positie' oid bijhouden in de tabel waarop je dan kunt sorteren bij het ophalen, en bij het updaten pas je die positie aan , etc...

[ Voor 38% gewijzigd door whoami op 30-03-2004 10:51 ]

https://fgheysels.github.io/


Verwijderd

wie zegt dat je ze netjes op alfabetisch volgorde kan binnen halen... :p

Als je met een up en down knopje werkt moet je gewoon de id's wisselen (ok, dan moet je wel ORDER BY id doen :))

Als je id's van belang zijn richting andere tabellen zou je een extra kolom moeten toevoegen met een volgnr!

  • Polderdijk
  • Registratie: December 2001
  • Laatst online: 19-05 14:10
Ja idd, daar heb ik de kolom Ranking voor aangemaakt.

Alleen het eruit halen en sorteren op Ranking is niet zo'n probleem :) alleen wat is nou een goede beredenering om die Ranking erin te stoppen. Ik wil dus dat je dmv een Up/Down knop naast elk record de huidige record 1 plaats naar boven of beneden kan sturen.

Dus de methode van de Ranking (dus positie) aanpassen weet ik ff geen oplossing voor...

Webhosting van SkyHost.nl: 25 Mb / 1 Gb windows hosting € 4,50 p/m excl.btw!


Verwijderd

Wat het nadeel van een positie bijhouden is, als je een partner omhoog gooit dan moet er ook één naar beneden. Dat vergt volgens mij 2 queries. Wat je kan doen is gewoon een bepaald niveau bijhouden en dan eerst op niveau sorteren en vervolgens op alfabet of zo. Kan overigens ook wel met positie, maar goed.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
Bij het saven:
alle records wissen, en opnieuw inserten met het juiste ranking-id. Dit is de gemakkelijkste weg als er, naast het wijzigen van positie, ook nieuwe records kunnen bijkomen, of bestaande records verwijderd worden.

https://fgheysels.github.io/


  • Polderdijk
  • Registratie: December 2001
  • Laatst online: 19-05 14:10
Verwijderd schreef op 30 maart 2004 @ 10:53:
wie zegt dat je ze netjes op alfabetisch volgorde kan binnen halen... :p

Als je met een up en down knopje werkt moet je gewoon de id's wisselen (ok, dan moet je wel ORDER BY id doen :))

Als je id's van belang zijn richting andere tabellen zou je een extra kolom moeten toevoegen met een volgnr!
Mmm, zoals ik al zij, ik zit weer veel te moeilijk te denken. Dan is het een kwestie van de getallen omswitchen in het Tabel Ranking en dan sorteren op Ranking :)

Dus ik zet bij de knop Down:
code:
1
OnClick="ranking.asp?van=<%=RS("Ranking")%>&naar=<%=RS("Ranking") + 1%>"

En bij de Up knop - 1 ipv + 1 :)

Bij een nieuw record is het even een query op Ranking en dit Id pakken en daar 1 bij optellen en deze gebruiken voor de ranking. Hierbij komt elke nieuwe onderaan de lijst!

Edit:
De ranking moet idd 2 keer gedaan worden, eerst Ranking 'van' naar Ranking 'naar' en daarna ook nog andersom. Ohw, wacht, ik moet ook nog het unieke id van het record meegeven, anders kan ik ze niet meer terug vinden :( Toch iets meer werk als ik dacht :)

Dan kunnen we bij de knop down dit gebruiken toch?
code:
1
OnClick="ranking.asp?id=<%=RS("id")%>&van=<%=RS("Ranking")%>&naar=<%=RS("Ranking") + 1%>"

En tijdens het updaten pakken we ook nog het Id van die ranking+1 en kunnen we deze ook 'omruilen', toch?

[ Voor 31% gewijzigd door Polderdijk op 30-03-2004 11:04 ]

Webhosting van SkyHost.nl: 25 Mb / 1 Gb windows hosting € 4,50 p/m excl.btw!


  • koli-man
  • Registratie: Januari 2003
  • Laatst online: 13-05 14:28

koli-man

Bartender!!!!

whoami schreef op 30 maart 2004 @ 10:58:
Bij het saven:
alle records wissen, en opnieuw inserten met het juiste ranking-id. Dit is de gemakkelijkste weg als er, naast het wijzigen van positie, ook nieuwe records kunnen bijkomen, of bestaande records verwijderd worden.
Dat is de makkelijkste weg, maar ook de veiligste? Ik bedoel, er zal maar net een servercrash o.i.d. komen net op het moment dat je de records hebt weggegooid? Want zoals ik het in de TS lees, is het maar één tabel waar die gegevens instaan.

[ Voor 8% gewijzigd door koli-man op 30-03-2004 11:10 ]

Hey Isaac...let's go shuffleboard on the Lido - deck...my site koli-man => MOEHA on X-Box laaaiiiff


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
koli-man schreef op 30 maart 2004 @ 11:06:
[...]


Dat is de makkelijkste weg, maar ook de veiligste? Ik bedoel, er zal maar net een servercrash o.i.d. komen net op het moment dat je de records hebt weggegooid? Want zoals ik het in de TS lees, is het maar één tabel waar die gegevens instaan.
Transacties. \o/.
Maar dat kent MySQL niet. :X

https://fgheysels.github.io/


  • koli-man
  • Registratie: Januari 2003
  • Laatst online: 13-05 14:28

koli-man

Bartender!!!!

whoami schreef op 30 maart 2004 @ 11:11:
[...]


Transacties. \o/.
Maar dat kent MySQL niet. :X
Jawel, dat kent mysql wel, maar dan wordt je databasetabeltype niet MyIsam maar InnoDB dacht ik...

[ Voor 3% gewijzigd door koli-man op 30-03-2004 11:17 ]

Hey Isaac...let's go shuffleboard on the Lido - deck...my site koli-man => MOEHA on X-Box laaaiiiff


Verwijderd

change.asp?id=3&type=up

dan kan je zoiets zeggen als (op fouten voorbehouden....):
VBScript:
1
2
3
4
5
6
7
8
9
10
11
If Request.Querystring("type") = "up" Then
  otherid = Request.Querystring("id") + 1
  UPDATE table SET ranking = ranking + 1 WHERE ranking = Request.Querystring("id")
  UPDATE table SET ranking = ranking - 1 WHERE ranking = otherid
End If

If Request.Querystring("type") = "down" Then
  otherid = Request.Querystring("id") - 1
  UPDATE table SET ranking = ranking - 1 WHERE ranking = Request.Querystring("id")
  UPDATE table SET ranking = ranking + 1 WHERE ranking = otherid
End If
Misschien zijn er el betere oplossingen, maar zoiets zou bijvoorbeeld kunnen, zeker omdat je ranking niet uniek hoeft te zijn.... Eventueel kan je (als je van MSSQL gebruik maakt de query's binnen een transaction uitvoeren zodat beide query's alleen doorgevoerd worden als beide lukken...)

  • Polderdijk
  • Registratie: December 2001
  • Laatst online: 19-05 14:10
@Whoami:
Ik gebruik MS SQL en geen MySQL :)

@Sooterd:
Dat is idd een nog makkelijkere oplossing! Ik zal even testen of het werkt en wat de aanpassingen zijn!
Toch gaat 't niet zo makkelijk, namelijk met de eerste update zorg je ervoor dat 2 records de zelfde Ranking waarde hebben, hierdoor moet je dus je UPDATE regelen met het unieke Id van het record. Dit kan door aan de href zowel de Id als de huidige Ranking mee te geven. En dan natuurlijk ook nog of hij Up of Down moet.

[ Voor 50% gewijzigd door Polderdijk op 30-03-2004 11:25 ]

Webhosting van SkyHost.nl: 25 Mb / 1 Gb windows hosting € 4,50 p/m excl.btw!


Verwijderd

Volgorde en regels schuiven doe ik als volgt.
Geef ieder record een volgnummer, maar laat er ruimte tussen. Dus bijvoorbeeld 10, 20, 30 etc.
Als je nu een record naar boven wilt verplaatsen, tel je 11 bij de volgorde op, of trek je er 11. ( een update dus ). Daarna moet je alle records op volgorder ophalen, en de nummers weer netjes maken.

Voor :
record1 volgorde 10
record2 volgorde 20
record3 volgorde 30

Als je nu record2 naar boven wilt verplaatsen, trek je 11 van de volgorder af
De situatie wordt dan

tussensituatie:
record2 volgorde 9
record1 volgorde 10
record3 volgorde 30

Daarna moet je even al je record afgaan en hernummeren. Dis kun je doen tijdens het opnieuw ophalen van de lijst.

Na :
record2 volgorde 10
record1 volgorde 20
record3 volgorde 30

Ok, het is niet echt efficient bij veel records, maar het werkt wel ! Je kunt natuurlijk nog wel een paar optimalisaties toevoegen ( je hoeft niet alle record te hernummeren etc. ), maar daar kun je zelf mee experimenteren.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
Polderdijk schreef op 30 maart 2004 @ 11:21:
@Sooterd:
Dat is idd een nog makkelijkere oplossing! Ik zal even testen of het werkt en wat de aanpassingen zijn!
Toch gaat 't niet zo makkelijk, namelijk met de eerste update zorg je ervoor dat 2 records de zelfde Ranking waarde hebben, hierdoor moet je dus je UPDATE regelen met het unieke Id van het record. Dit kan door aan de href zowel de Id als de huidige Ranking mee te geven. En dan natuurlijk ook nog of hij Up of Down moet.
Ik vind dat zo geen goede oplossing.
stel dat je een record 5 posities naar voren wil schuiven: dat wil zeggen dat je 10 queries moet uitvoeren.
Je kan het verschuiven beter client-side laten gebeuren oid, en dan, door op een 'submit' knop te klikken dmv 2 queries alle records te deleten, en dan opnieuw te inserten.

https://fgheysels.github.io/


Verwijderd

whoami schreef op 30 maart 2004 @ 11:55:

Ik vind dat zo geen goede oplossing.
stel dat je een record 5 posities naar voren wil schuiven: dat wil zeggen dat je 10 queries moet uitvoeren.
OK, maar vanuit de vraagstelling werd gezegd dat hij steeds één record wou verplaatsen... vandaar mijn suggestie...

Daarnaast zij het geen 10 query's want je kan dan gewoon zeggen

UPDATE table SET ranking = ranking + 1 WHERE id > 5 (of vertaaltie het onderwater naar meerdere query's vraag ik me nu af)

  • Jaspertje
  • Registratie: September 2001
  • Laatst online: 18-05 15:53

Jaspertje

Max & Milo.. lief

Een hele simpele query:

SQL:
1
Update table set ranking = ranking+1 where ranking > 4 And UniekId <> hetrecordwat4 moet worden

Hier schuift alles 1 plek op behalve het record wat je naar 4 verplaatst.

Hierdoor heb je 2 queries. Eentje voor het zetten van die nieuwe rank, en eentje voor het opschuiven

het kan ook andersom, als je alles naar benee wilt schuiven, met 1- ..

net te laat...

[ Voor 22% gewijzigd door Jaspertje op 30-03-2004 12:02 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
Verwijderd schreef op 30 maart 2004 @ 12:00:
[...]


OK, maar vanuit de vraagstelling werd gezegd dat hij steeds één record wou verplaatsen... vandaar mijn suggestie...

Daarnaast zij het geen 10 query's want je kan dan gewoon zeggen
Als jij iedere keer je op die Up of Down button klikt, een query uitvoert, en je klikt er 5x op, dan heb je 10 queries, en 5 roundtrips.
UPDATE table SET ranking = ranking + 1 WHERE id > 5 (of vertaaltie het onderwater naar meerdere query's vraag ik me nu af)
:? Waarom zou ie dat doen?

https://fgheysels.github.io/


Verwijderd

sorry, ja zat ff op een andere manier te denken... let dus maar niet op mn geblaat in de vorige reply :)

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 08:05

BCC

Eeh, waarom zet je niet gewoon de commit uit.. doe je al je ranking dingen en als je vind dat alles goed staat stuur je een commit?

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
BCC schreef op 30 maart 2004 @ 12:06:
Eeh, waarom zet je niet gewoon de commit uit.. doe je al je ranking dingen en als je vind dat alles goed staat stuur je een commit?
Als je een query doet zonder commit, veroorzaakt dat ook nog een roundtrip, en wordt die query ook uitgevoerd.
Andere sessies kunnen die wijziging echter alleen nog niet zien, omdat de wijzigingen nog niet gecommited zijn. (That is: als je transaction isolation level minstens op 'READ COMMITED' staat).

https://fgheysels.github.io/


  • BCC
  • Registratie: Juli 2000
  • Laatst online: 08:05

BCC

whoami schreef op 30 maart 2004 @ 12:11:
[...]


Als je een query doet zonder commit, veroorzaakt dat ook nog een roundtrip, en wordt die query ook uitgevoerd.
Andere sessies kunnen die wijziging echter alleen nog niet zien, omdat de wijzigingen nog niet gecommited zijn. (That is: als je transaction isolation level minstens op 'READ COMMITED' staat).
Tja, wil je een corrupte database of niet :)?

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09-2025

d00d

geen matches

Hoi Polderdijk,

Je zit op de goede weg. Een Ranking veld om de positie te bepalen is inderdaad de juiste manier, deze telt gewoon van 1 tot n (n is het aantal records), iedere keer dat de gebruiker op de knop naar boven of naar onderen klikt wordt een stored procedure uitgevoerd (er vanuit gaande dat je SQL Server en niet MySQL gebruikt).

create table partner (ranking int, name varchar(100))
go
insert into partner values (1, 'Microsoft')
go
insert into partner values (2, 'Sun')
go
insert into partner values (3, 'ATI')
go
insert into partner values (4, 'IBM')
go

drop proc PartnerUpDown
go
create proc PartnerUpDown (
@ranking int,
@direction bit = 1
)
as
declare @maxrank int
set nocount on
/* @direction heeft als default waarde 1, hij gaat omhoog, bij 0 gaat hij naar beneden */
if (@ranking <> 1 and @direction = 1) begin
update partner set ranking = 0 where ranking = @ranking
update partner set ranking = ranking + 1 where ranking = (@ranking - 1)
update partner set ranking = @ranking - 1 where ranking = 0
return 0
end

select @maxrank = max(ranking) from partner
if (@ranking <> @maxrank and @direction = 0) begin
update partner set ranking = 0 where ranking = @ranking
update partner set ranking = ranking - 1 where ranking = (@ranking + 1)
update partner set ranking = @ranking + 1 where ranking = 0
end
return 0

Succes,
Daniel

42.7 percent of all statistics are made up on the spot.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
d00d schreef op 30 maart 2004 @ 13:26:
Hoi Polderdijk,

Je zit op de goede weg. Een Ranking veld om de positie te bepalen is inderdaad de juiste manier, deze telt gewoon van 1 tot n (n is het aantal records), iedere keer dat de gebruiker op de knop naar boven of naar onderen klikt wordt een stored procedure uitgevoerd (er vanuit gaande dat je SQL Server en niet MySQL gebruikt).
Tja, ik blijf bij mijn argument: waarom iedere keer een roundtrip naar de server veroorzaken als er op die knop geklikt wordt, ipv client-side eerst de volgorde te gaan bepalen, en dan dmv 1 klik op een knop, 1 roundtrip naar de server te doen en alles te gaan wegschrijven.

Welke optie is er het best voor de user experience denk je?

https://fgheysels.github.io/


  • Polderdijk
  • Registratie: December 2001
  • Laatst online: 19-05 14:10
Whoami, ik ben het wel met je eens dat je jouw beredenering beter kan doen als er echt veel gebruikers mee moeten werken.

Echter dit is alleen voor de admins van de site (ik en nog iemand) en zovaak wordt het niet gebruikt. Misschien 2 keer in de week. Dus die paar keer een 'zware' load op de SQL maakt ook niet uit toch?

Die stored precedure klinkt wel mooi enzo, alleen ik kan dat script wel c/p-en maar omdat ik zelf nog weinig verstand ervan hebt doe ik het liever allemaal met ASP. Maar toch iig bedankt voor je toevoeging :)

Ik heb ook al een stukje gemaakt, met dus idd 2 QUERY's per move, maar er gaat nog 1 ding fout dus dat ga ik nu ff proberen op te lossen.

Webhosting van SkyHost.nl: 25 Mb / 1 Gb windows hosting € 4,50 p/m excl.btw!


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:32
Polderdijk schreef op 30 maart 2004 @ 14:13:

Echter dit is alleen voor de admins van de site (ik en nog iemand) en zovaak wordt het niet gebruikt. Misschien 2 keer in de week. Dus die paar keer een 'zware' load op de SQL maakt ook niet uit toch?
Het is geen kwestie van zware load, het is een kwestie van trage responsiveness van de site voor de gebruiker.
Iedere keer dat jij op die button klikt, moet er een post naar de server gebeuren.

https://fgheysels.github.io/

Pagina: 1