INSTEAD OF INSERT-Trigger
Mithilfe von INSTEAD OF INSERT-Triggern für eine Sicht oder eine Tabelle können die Standardaktionen der INSERT-Anweisung ersetzt werden. Normalerweise wird der INSTEAD OF INSERT-Trigger für eine Sicht definiert, um Daten in mindestens eine Basistabelle einzufügen.
Die Spalten in der Auswahlliste der Sicht können Spalten sein, die NULL-Werte zulassen oder die keine NULL-Werte zulassen. Wenn eine Sichtspalte keine NULL-Werte zulässt, muss eine INSERT-Anweisung Werte für die Spalte bereitstellen. Sichtspalten lassen NULL-Werte zu, wenn der Ausdruck, der die Sichtspalte definiert, die folgenden Elemente enthält:
- Verweise auf Basistabellenspalten, die NULL-Werte zulassen
- Arithmetische Operatoren
- Verweise auf Funktionen
- CASE oder COALESCE mit einem untergeordneten Ausdruck, der NULL-Werte zulässt
- NULLIF
Mithilfe der von der COLUMNPROPERTY-Funktion gemeldeten AllowsNull-Eigenschaft können Sie bestimmen, ob eine Sichtspalte NULL-Werte zulässt. Die gespeicherte sp_help-Prozedur meldet ebenfalls, welche Sichtspalten NULL-Werte zulassen.
Eine INSERT-Anweisung, die auf eine Sicht verweist, die einen INSTEAD OF INSERT-Trigger aufweist, muss für jede Sichtspalte, die keine NULL-Werte zulässt, Werte angeben. Dazu zählen Sichtspalten, die auf Spalten in der Basistabelle verweisen, für die keine Eingabewerte angegeben werden können, wie z. B.:
- Berechnete Spalten in der Basistabelle.
- Identitätsspalten in der Basistabelle, für die IDENTITY INSERT auf OFF festgelegt ist.
- Basistabellenspalten vom timestamp-Datentyp.
Falls der INSTEAD OF INSERT-Sichttrigger mit den Daten in der inserted-Tabelle eine INSERT-Anweisung für die Basistabelle generiert, müssen die Werte für diese Spaltentypen ignoriert werden, ausgenommen die Spalten in der Auswahlliste der INSERT-Anweisung. Die INSERT-Anweisung kann Pseudowerte für diese Spaltentypen generieren.
Zwar muss z. B. eine INSERT-Anweisung einen Wert für eine Sichtspalte angeben, die einer Identitätsspalte oder einer berechneten Spalte in einer Basistabelle zugeordnet ist, sie kann jedoch einen Platzhalterwert angeben. Der INSTEAD OF-Trigger kann den eingegebenen Wert beim Erstellen der INSERT-Anweisung ignorieren, die die Werte in die Basistabelle einfügt.
Die folgenden Anweisungen erstellen eine Tabelle, eine Sicht und einen Trigger, mit denen dieser Prozess veranschaulicht wird:
CREATE TABLE BaseTable
(PrimaryKey int PRIMARY KEY IDENTITY(1,1),
Color nvarchar(10) NOT NULL,
Material nvarchar(10) NOT NULL,
ComputedCol AS (Color + Material)
)
GO
--Create a view that contains all columns from the base table.
CREATE VIEW InsteadView
AS SELECT PrimaryKey, Color, Material, ComputedCol
FROM BaseTable
GO
--Create an INSTEAD OF INSERT trigger on the view.
CREATE TRIGGER InsteadTrigger on InsteadView
INSTEAD OF INSERT
AS
BEGIN
--Build an INSERT statement ignoring inserted.PrimaryKey and
--inserted.ComputedCol.
INSERT INTO BaseTable
SELECT Color, Material
FROM inserted
END
GO
Eine INSERT
-Anweisung, die direkt auf BaseTable
verweist, kann keinen Wert für die Spalten PrimaryKey
und ComputedCol
angeben. Beispiel:
--A correct INSERT statement that skips the PrimaryKey and ComputedCol columns.
INSERT INTO BaseTable (Color, Material)
VALUES (N'Red', N'Cloth')
--View the results of the INSERT statement.
SELECT PrimaryKey, Color, Material, ComputedCol
FROM BaseTable
--An incorrect statement that tries to supply a value for the
--PrimaryKey and ComputedCol columns.
INSERT INTO BaseTable
VALUES (2, N'Green', N'Wood', N'GreenWood')
Jedoch muss eine INSERT
-Anweisung, die auf InsteadView
verweist, einen Wert für PrimaryKey
und ComputedCol
angeben:
--A correct INSERT statement supplying dummy values for the
--PrimaryKey and ComputedCol columns.
INSERT INTO InsteadView (PrimaryKey, Color, Material, ComputedCol)
VALUES (999, N'Blue', N'Plastic', N'XXXXXX')
--View the results of the INSERT statement.
SELECT PrimaryKey, Color, Material, ComputedCol
FROM InsteadView
Die inserted-Tabelle, die an InsteadTrigger
übergeben wird, wird mit den PrimaryKey
- und ComputedCol
-Spalten erstellt, die keine NULL-Werte zulassen. Aus diesem Grund muss die INSERT
-Anweisung, die auf die Sicht verweist, einen Wert für diese Spalten angeben. Die Werte 999
und N'XXXXXX'
werden an InsteadTrigger
übergeben, aber die INSERT
-Anweisung im Trigger wählt weder inserted.PrimaryKey
noch inserted.ComputedCol
aus. Daher werden die Werte ignoriert. Die Zeile, die tatsächlich in BaseTable
eingefügt wird, enthält 2
in PrimaryKey
und N'BluePlastic'
in ComputedCol
.
Die Werte, die in der inserted-Tabelle für berechnete Spalten, Identitätsspalten und timestamp-Spalten enthalten sind, sind für INSTEAD OF INSERT-Trigger, die für Tabellen angegeben sind, und für INSTEAD OF-Trigger, die für Sichten angegeben sind, unterschiedlich.
Basistabellenspalte | Wert in eingefügter Tabelle in INSERT-Triggern für eine Tabelle | Wert in eingefügter Tabelle in einem INSTEAD OF INSERT-Trigger für eine Sicht |
---|---|---|
Die Spalte ist eine berechnete Spalte. |
Berechneter Ausdruck |
Vom Benutzer angegebener Wert oder NULL |
Die Spalte besitzt eine IDENTITY-Eigenschaft. |
0, wenn IDENTITY_INSERT auf OFF festgelegt ist; angegebener Wert, wenn IDENTITY_INSERT auf ON festgelegt ist |
Vom Benutzer angegebener Wert oder NULL |
Hat einen timestamp-Datentyp. |
Binärnullen, wenn die Spalte keine NULL-Werte zulässt, und NULL, wenn die Spalte NULL-Werte zulässt |
Vom Benutzer angegebener Wert oder NULL |
Eine INSERT-Anweisung, die direkt auf eine Basistabelle verweist, muss keine Werte für eine NOT NULL-Spalte angeben, die auch eine DEFAULT-Definition aufweist. Falls die INSERT-Anweisung keinen Wert angibt, wird der Standardwert verwendet. Verweist jedoch ein einfacher Ausdruck in einer Sicht, die einen INSTEAD OF INSERT-Trigger enthält, auf eine NOT NULL-Spalte mit einer DEFAULT-Definition, muss jede INSERT-Anweisung, die auf diese Sicht verweist, einen Wert für die Spalte angeben. Dieser Wert ist erforderlich, um die inserted-Tabelle zu erstellen, die an den Trigger übergeben wird. Für einen Wert, der dem Trigger signalisiert, dass der Standardwert verwendet werden soll, ist eine Konvention erforderlich. Die optimale Konvention ist, dass die INSERT-Anweisung den Standardwert angibt.
Die deleted-Tabelle in einem INSTEAD OF INSERT-Trigger ist immer leer.
Siehe auch
Andere Ressourcen
COLUMNPROPERTY (Transact-SQL)
sp_help (Transact-SQL)