Kann ich eine Ansicht zum Bearbeiten der ID-Zuordnungstabelle erstellen, ohne die IDs zu sehen?


2

Ich habe 2 Tabellen, A und B mit einem Primärschlüssel int und einem Namen string .

Ich habe eine dritte Tabelle, C, mit 2 Spalten, die die IDs von A und B zusammen abbilden.Ich möchte einen Blick darauf werfenbearbeitendie Zuordnungen in Tabelle C, aber ich möchte, dass die Ansicht den Wert Name und nicht den Wert IDs .Die Ansicht würde über SQL Server Management Studio bearbeitet.

In der Ansicht sollte der Benutzer beispielsweise "Item4" in die Spalte "Item" und "Accessory1" in die Spalte "Accessory" eingeben können. Tabelle C wird mit einer neuen Zeilenzuordnung "4" zu "1" aktualisiert.

enter image description here

Ich frage mich, ob ich dies zu einer bearbeitbaren Ansicht machen kann, damit ich nicht die Mühe habe, eine ganze Anwendung zu schreiben, um dies zu verwalten.

Wenn ich zur Ansicht in Microsoft SQL Server Management Studio gehe und mit der rechten Maustaste klicke, kann ich die obersten 200 Zeilen bearbeiten.Ich weiß, dass die Einschränkung für diese Funktion darin besteht, dass ich nur Änderungen an einer einzelnen Tabelle vornehmen kann.Ich würde nur eine einzelne Tabelle bearbeiten, also könnte es eine Möglichkeit geben, dies zum Laufen zu bringen.Gibt es einen Weg?(Meine Benutzer sind Personen (Händler), die mit SQL Server vertraut sind und direkten Zugriff auf ihre Daten bevorzugen.)

  0

@Franchesca In Bezug auf "_ (Meine Benutzer sind mit MS SQL vertraut und bevorzugen den direkten Zugriff auf ihre Daten) _": Werden Ihre Benutzer diese Daten auf die gleiche Weise wie Sie bearbeiten und Zeilen direkt in SSMS bearbeiten (etwas, das selten eine gute Option ist)?Oder wollen sie eine UPDATE-Anweisung ausgeben?Wenn sie direkten Zugriff haben möchten, warum schließen Sie das UPDATE nicht einfach in eine gespeicherte Prozedur ein, die beide Zeichenfolgenwerte akzeptiert und die Aktualisierung entsprechend durchführt? 11 okt. 162016-10-11 14:05:42

  0

@srutzky, denn dann können Sie Ihre Zeilen nicht aus Excel kopieren und einfügen.: D 11 okt. 162016-10-11 14:10:13

+1

@Franchesca Wie erhält Excel überhaupt die Werte für diese Zeilen?Geben die Benutzer sie von Hand in Excel ein oder wird sie direkt aus SQL Server abgerufen?Was ist mit Tippfehlern, wenn sie von Hand eingegeben wurden? 11 okt. 162016-10-11 14:21:33

  0

@srutzky Mit großer Kraft geht große Verantwortung einher.Woher die Daten stammen, hängt vom Benutzer und dessen Aktivitäten ab. Die Aktivitäten können sich kurzfristig ändern. 12 okt. 162016-10-12 11:14:48

6

Basistabellen

CREATE TABLE dbo.Item
(
     ItemID integer PRIMARY KEY,
     ItemName varchar(50) NOT NULL UNIQUE
);

CREATE TABLE dbo.Accessory
(
     AccessoryID integer PRIMARY KEY,
     AccessoryName varchar(50) NOT NULL UNIQUE
);

CREATE TABLE dbo.ItemAccessory
(
     ItemID integer REFERENCES dbo.Item (ItemID),
     AccessoryID integer REFERENCES dbo.Accessory (AccessoryID),

     PRIMARY KEY (ItemID, AccessoryID)
);

Beispieldaten

INSERT dbo.Item
     (ItemID, ItemName)
VALUES
     (1, 'Item 1'),
     (2, 'Item 2'),
     (3, 'Item 3'),
     (4, 'Item 4');

INSERT dbo.Accessory
     (AccessoryID, AccessoryName)
VALUES
     (1, 'Accessory 1'),
     (2, 'Accessory 2'),
     (3, 'Accessory 3'),
     (4, 'Accessory 4');

INSERT dbo.ItemAccessory
     (ItemID, AccessoryID)
VALUES
     (1, 1),
     (1, 2),
     (2, 3),
     (3, 4);

Aussicht

CREATE VIEW dbo.ItemAccessoryName
WITH SCHEMABINDING
AS
SELECT
     I.ItemName,
     A.AccessoryName
FROM dbo.ItemAccessory AS IA
JOIN dbo.Accessory AS A
     ON A.AccessoryID = IA.AccessoryID
JOIN dbo.Item AS I
     ON I.ItemID = IA.ItemID;

Problem

Die Ansicht kann nicht direkt aktualisiert werden:

INSERT dbo.ItemAccessoryName
     (ItemName, AccessoryName)
VALUES
     ('Item 4', 'Accessory 4');

Nachricht 4405, Ebene 16, Status 1, Zeile 61
Die Ansicht oder Funktion 'dbo.ItemAccessoryName' kann nicht aktualisiert werden, da die Änderung mehrere Basistabellen betrifft.

Lösung

Wir können jede Ansicht mit einem anstelle des Triggers aktualisierbar machen:

CREATE TRIGGER dbo_ItemAccessoryName_IOI
ON dbo.ItemAccessoryName
INSTEAD OF INSERT
AS
     SET ROWCOUNT 0;
     SET NOCOUNT ON;

     INSERT dbo.ItemAccessory
     (
       ItemID, 
       AccessoryID
     )
     SELECT
       I.ItemID,
       A.AccessoryID 
     FROM Inserted AS INS
     JOIN dbo.Item AS I
       ON I.ItemName = INS.ItemName
     JOIN dbo.Accessory AS A
       ON A.AccessoryName = INS.AccessoryName;

Der Trigger konvertiert im Wesentlichen die angegebenen Namen in IDs, bevor das Einfügen versucht wird.Solange Sie eine gute referenzielle Integrität haben, sollte der Bedarf an zusätzlichen Überprüfungen im Triggercode minimal sein.Die Details hängen davon ab, was genau geschehen soll, wenn jemand mehrere Einträge einfügt, von denen beispielsweise nur einige gültig sind.

Fügt ein, aktualisiert und löscht

Sie benötigen zusätzliche Triggerlogik, wenn Sie (allgemeine) Aktualisierungen und Löschvorgänge in der Ansicht zulassen möchten.Zum Beispiel:

DROP TRIGGER dbo.dbo_ItemAccessoryName_IOI;
GO
CREATE TRIGGER dbo_ItemAccessoryName_IOIUD
ON dbo.ItemAccessoryName
INSTEAD OF INSERT, UPDATE, DELETE
AS
     SET ROWCOUNT 0;
     SET NOCOUNT ON;

     -- Handle deletions (including the delete part of an update)
     DELETE IA
     FROM dbo.ItemAccessory AS IA
     JOIN dbo.Item AS I
       ON I.ItemID = IA.ItemID
     JOIN dbo.Accessory AS A
       ON A.AccessoryID = IA.AccessoryID
     JOIN Deleted AS DEL
       ON DEL.ItemName = I.ItemName
       AND DEL.AccessoryName = A.AccessoryName;

     -- Handle inserts (including the insert part of an update)
     INSERT dbo.ItemAccessory
     (
       ItemID, 
       AccessoryID
     )
     SELECT
       I.ItemID,
       A.AccessoryID 
     FROM Inserted AS INS
     JOIN dbo.Item AS I
       ON I.ItemName = INS.ItemName
     JOIN dbo.Accessory AS A
       ON A.AccessoryName = INS.AccessoryName;