[SQL] 'Rangorde' probleem.

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

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Situatie:

Je hebt een tabel met items, die per categorie gesorteerd worden. Dus je hebt cat1, item1, item2, item3, cat2 item1, item2, cat3, etc. Iedere cat en rang combinatie mag dus maar één keer voorkomen. Ook mogen er eigenlijk geen gaten tussen de items zitten (item2, item3 mag dus niet).

Vraag:

Is het mogelijk om met alleen SQL en met een Unique ingesteld op de cat en rang kolommen de gewijzigde posities aan te passen van item 1 t/m n?


Dat het gaat met wat code en zonder unique dat weet ik natuurlijk wel. Maar in principe is het zo dat je zo veel mogelijk afdwingt op databaseniveau, en het gewoon een feit is dat je nooit dezelfde combinatie cat en item kunt hebben.

iOS developer


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
BikkelZ schreef op maandag 07 mei 2007 @ 12:09:
en het gewoon een feit is dat je nooit dezelfde combinatie cat en item kunt hebben.
Geen idee of ik je topic verder goed begrijp maar een samengestelde sleutel (compound key) is wat je zoekt hier.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
RobIII schreef op maandag 07 mei 2007 @ 12:13:
[...]

Geen idee of ik je topic verder goed begrijp maar een samengestelde sleutel (compound key) is wat je zoekt hier.
Dat voorkomt inderdaad foutieve ingave.

Om de goede nummers te genereren moet je nog wat meer doen. Je zult de hele tabel moeten locken bij een insert, bepalen wat per cat het hoogte nummer is en de insert doen.

Maar wat is nu precies je vraag? Je hebt het nu verkeerd en je zoekt een query om het eenmalig te updaten, of zoek je de insert-routine om nieuwe records toe te voegen.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Je hebt dus een ID (pri) maar de catID en de rangorde moeten samen ook uniek zijn.

Stel dat ik de rang van item 1 in 2 verander en die van 2 in 1.

Als ik die van 1 in 2 verander, dan krijg ik een error, want die combinatie bestaat al.

Dus dat moet ik of met scripts de boel gaan oplossen, of ik haal de unique er af en dwing het dus niet meer op databaseniveau af.

Of is er nog een nette oplossing via SQL? Een soort van stoelendans achtige procedure?

[ Voor 31% gewijzigd door BikkelZ op 07-05-2007 12:32 ]

iOS developer


Verwijderd

Twee updates in één transactie uitvoeren...

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Verwijderd schreef op maandag 07 mei 2007 @ 21:49:
Twee updates in één transactie uitvoeren...
Gaat er tijdens een transactie pas een duplicate key error optreden nadat dat na COMMIT nog steeds inderdaad zo is?

iOS developer


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dat had je zelf al kunnen testen, 2 update statements schrijven met een begin; en commit; er omheen is 10 seconde werk. Je krijgt nog steeds de error, en ook disable / enable keys biedt geen soelaas.

xaprb, een redelijk interessante mysql blog, heeft 2 gerelateerde artikelen:
xaprb: How to avoid unique index violations on updates in MySQL en xaprb: How to reverse a sequence in SQL. Uitkomst is dat er geen mooie methode is.
Ik zou (totdat iemand toch een mooiere methode aandraagt), met 3 updates werken. Begin transactie, order van a op null zetten, b wordt oude waarde a, a wordt oude waarde b, commit.

Overigens zeg je nergens dat je expliciet welk dbms je gebruikt, dus het kan zijn dat bij een andere db het wel mooier kan. MySQL controleert iig continu de unique constraints, terwijl soms een wat meer laid back aanpak gewenst zou zijn (zie 2e link voor voorbeeld van dit gedrag).

{signature}


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Voutloos schreef op dinsdag 08 mei 2007 @ 09:04:
Dat had je zelf al kunnen testen, 2 update statements schrijven met een begin; en commit; er omheen is 10 seconde werk. Je krijgt nog steeds de error, en ook disable / enable keys biedt geen soelaas.
Ik had niet echt het gevoel dat dat ging weken om heel eerlijk te zijn....
Voutloos schreef op dinsdag 08 mei 2007 @ 09:04:xaprb, een redelijk interessante mysql blog, heeft 2 gerelateerde artikelen:
xaprb: How to avoid unique index violations on updates in MySQL en xaprb: How to reverse a sequence in SQL. Uitkomst is dat er geen mooie methode is.
Ik zou (totdat iemand toch een mooiere methode aandraagt), met 3 updates werken. Begin transactie, order van a op null zetten, b wordt oude waarde a, a wordt oude waarde b, commit.
Hmmm die XOR die kende ik nog niet, die is wel grappig maar dat werkt alleen bij twee waardes die van te voren bekend zijn natuurlijk. Eigenlijk wordt er dus bevestigd dat het niet anders dan ingewikkeld, vies, of een combinatie daarvan kan.
Voutloos schreef op dinsdag 08 mei 2007 @ 09:04:Overigens zeg je nergens dat je expliciet welk dbms je gebruikt, dus het kan zijn dat bij een andere db het wel mooier kan. MySQL controleert iig continu de unique constraints, terwijl soms een wat meer laid back aanpak gewenst zou zijn (zie 2e link voor voorbeeld van dit gedrag).
Meestal MySQL, maar als er SQL DBMS'en zijn die dit soort dingen voor me oplossen dan wil ik daar best wel wat over horen :)

iOS developer


Verwijderd

Voutloos schreef op dinsdag 08 mei 2007 @ 09:04:
Dat had je zelf al kunnen testen, 2 update statements schrijven met een begin; en commit; er omheen is 10 seconde werk. Je krijgt nog steeds de error, en ook disable / enable keys biedt geen soelaas.
Stom van mij, had ik kunnen weten. Even te simpel gedacht :).

Maar wat je kan doen is updaten in één statement door een CASE..THEN... Je krijgt dan bijv:
SQL:
1
2
3
4
5
6
UPDATE dbo.Test
 SET SeqId = CASE SeqId
                WHEN 1 THEN 2
                WHEN 2 THEN 1
             END
    WHERE SeqId IN (1, 2)

Heb het nog even getest en dit werkt in ieder geval op SQL Server.
Pagina: 1