1. Eindeutige Schlüssel ändert man nicht.
2. In Firebird könnte es so aussehen:
SQL-Code:
select '
update gruppen set position = '||row_number()
over ()||'
where gruppenid = '||gruppenid||'
and id = '||id
as sql
from gruppen
where gruppenid = :GruppenID
order by id
3. In
MSSQL könnte es so aussehen:
SQL-Code:
select concat('
update gruppen set position = ',row_number()
over (),'
where gruppenid = ',id,'
and id = ',g.id,'
;')
as sql
from gruppen
where gruppenid = :Gruppenid
order by id
Firebird baut Strings halt mit || zusammen,
MSSQL mit Concat.
Damit FireBird auch mit Concat arbeiten kann, muss man sich eine passende Funktion bauen, die dann in die Scripte zum Datenbankaufbau mit rein muss:
SQL-Code:
SET TERM !!;
CREATE or alter function concat (
v1 varchar(2000),
v2 varchar(2000) default '',
v3 varchar(2000) default '',
v4 varchar(2000) default '',
v5 varchar(2000) default '',
v6 varchar(2000) default '',
v7 varchar(2000) default '',
v8 varchar(2000) default '',
v9 varchar(2000) default ''
)
returns varchar(2000)
AS
BEGIN
return v1||v2||v3||v4||v5||v6||v7||v8||v9;
END!!
SET TERM ;!!
Nachteil: Concat von
MSSQL kann bis zu 254 Parameter annehmen, die aber nicht angegeben werden müssen.
Ob diese "Wahlfreiheit" bei FireBird möglich ist, hab' ich nicht herausbekommen. Bei obiger Lösung müssen sie alle angegeben werden (deshalb hab' ich mal bei neun Parametern aufgehört).
Als Ergebnis käme ein
SQL heraus, das dann unter
MSSQL und FireBird funktionieren sollte:
SQL-Code:
select concat('
update gruppen set position = ',row_number()
over (),'
where gruppenid = ',id,'
and id = ',id,'
;','
','
')
as sql
from gruppen
where gruppenid = :Gruppenid
order by id
Die als Ergebnis erstellten Updatestatements müssten nun noch in 'ner Schleife, einem Executeblockkonstrukt, das für beide Datenbanken praktikabel ist, o. ä. ausgeführt werden.
Und nein, es ist keine gute Idee, einen eindeutigen Schlüssel zu ändern.
Wird hier der "Unique Key" nur als "datenbankseitige Hilfe" genutzt, um auf Fehler beim Setzen der Position hinzuweisen, mag es angehen. Es muss aber sichergestellte sein, dass niemand, wirklich niemand, die Kombination von GruppenID und Position in irgendeiner Form (ggfls., unter Umständen eventuell, vielleicht, auch nur ansatzweise) als Schlüssel verwendet. Flapsig formuliert: Der "Unique Key" darf alles sein, nur kein "Unique Key", sondern nur ein Konstrukt, das "irgendwie (datenbankseitig) geeignet ist", Positionsdubletten innerhalb einer GruppenID zu verhindern.
Funktioniert die Lösung?
Vielleicht.
Ist sie Industriestandard oder etwas, das diesem (wenn auch nur ansatzweise) ähnlich sein könnte?
Nein, sicherlich nicht.
Hilft sie bei der Behebung eines Problemes, das bisher unter "Missbrauch" eines "Unique Keys" gelöst werden konnte?
Eventuell.
PS: Funktion und
SQL funktionieren unter FireBird.
MSSQL hab' ich nicht, daher kann ich hier nur darauf hoffen, dass es funktionieren könnte. Als Idee sollte es aber ausreichen.