Ist es möglich, eine Spalte nur lesbar zu machen?


25

Ich bin gespannt, ob es möglich ist, eine Tabelle mit einer Spalte zu erstellen, die niemals geändert werden kann, die anderen Spalten der Tabelle jedoch.

Zum Beispiel könnte ich mir eine CreatedByUserSpalte vorstellen , die niemals geändert werden sollte.

Gibt es eine integrierte Funktionalität in SQL Server dafür, oder ist es nur über Trigger oder etwas anderes möglich?


Ich glaube nicht, dass es eine andere Möglichkeit gibt, als Trigger zu implementieren und nur Anweisungen über Prozeduren zu erstellen / zu aktualisieren / zu löschen.
Mark S. Rasmussen


@MartinSmith danke, für den Link. Ich denke, das wäre die Antwort auf meine Frage. Also machen Sie eine Antwort und ich werde es akzeptieren.
Philipp M

Antworten:


19

Es gibt keine deklarative Unterstützung für nicht aktualisierbare Spalten (außer für bestimmte vordefinierte Fälle wie IDENTITY).

Dieses Connect-Objekt hat es angefordert, wurde jedoch abgelehnt. Fügen Sie DRI hinzu, um unveränderliche Spaltenwerte zu erzwingen

Ein UPDATEAuslöser wäre wahrscheinlich der robusteste Weg, um dies zu erreichen. Es könnte IF UPDATE(CreatedByUser)einen Fehler prüfen und auslösen und die Transaktion rückgängig machen, wenn dies wahr ist.


Archive.org-Link zu altem oben verlinktem Connect-Anforderungselement: web.archive.org/web/20130402211121/http://connect.microsoft.com/…
Anssssss

7

Ich habe den UPDATE TRIGGERvon Martin Smith vorgeschlagenen Ansatz folgendermaßen umgesetzt:

CREATE TRIGGER trgAfterUpdateAsset ON dbo.Asset
FOR UPDATE AS
IF UPDATE(AssetTypeID) AND EXISTS (SELECT * FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.AssetTypeID <> d.AssetTypeID)
BEGIN 
    RAISERROR ('AssetTypeID cannot change.', 16, 1);
    ROLLBACK TRAN
END     

(Hinweis: Die Tabelle enthält eine Primärschlüsselspalte mit der Bezeichnung ID.)

Ich lehne das Update nur ab, wenn sich der Wert von AssetTypeID ändert. Die Spalte könnte also in einem Update vorhanden sein, und wenn sich der Wert nicht ändert, wird sie durchgelassen. (Ich brauchte diesen Weg)


1
Wenn für einen bestimmten Datensatz der AssetTypeIDWert auf einen Wert ungleich Null festgelegt ist und Sie ausführen, UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_iddass kein Rollback erfolgt, da WHERE i.AssetTypeID <> d.AssetTypeIDder Trigger den Wert false ergibt und diese Spalte bearbeitbar bleibt.
Christiaan Westerbeek

3

Sie können eine Ansicht mit abgeleiteter Spalte verwenden. Versuche dies

create table ro_test(id int primary key, CreatedByUser int)
go
create view v_ro_test
as
select id, CreatedByUser*1 CreatedByUser from ro_test
go

insert into ro_test values(1,10);
update ro_test
set CreatedByUser =11
where id =1;
select * from v_ro_test;
go
--ERROR--
update v_ro_test
set CreatedByUser =10
where id =1;

--BUT--
update v_ro_test
set id =2
where id =1;
select * from v_ro_test;

Ich bin mir nicht sicher was du meinst. Können Sie näher darauf eingehen?
Philipp M

Sie können die Tabelle aber einfach aktualisieren und ihre Werte ändern
Philipp M

1
@Philipp M Sie können jedoch den Zugriff auf die Tabelle widerrufen und der Ansicht gewähren. Tut es nicht?
msi77

-3

Warum aktualisieren Sie die von Spalte erstellt?

Ich hätte zwei Spalten, eine [created_by] - und eine [modified_by] -Spalte, in die beim ersten Einfügen alle entsprechenden Spalten im Datensatz eingefügt würden, und alle nachfolgenden Aktualisierungen würden nur die [modified_by] -Spalte aktualisieren (über einen Auslöser in der Anwendung) Sie können Ihr Update so strukturieren, dass nur [modified_by] und die entsprechenden Spalten geändert werden.)


3
Ich denke, Sie haben den Punkt der Frage verpasst. Es wurde gefragt, ob eine eingebaute Unterstützung vorhanden ist, um genau zu erzwingen, dass die Spalte nicht aktualisierbar ist.
Martin Smith

@MartinSmith Genau - wir haben auch eine geänderte Spalte und ich war nur neugierig, ob eine eingebaute Unterstützung für readonly existiert
Philipp M
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.