Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:SQL Server
Azure SQL-Datenbank
Azure SQL Managed Instance
Das Transact-SQL Codebeispiel in diesem Abschnitt veranschaulicht, wie Sie die T-SQL-Anweisung MERGE in einem systemeigenen kompilierten Modul simulieren können. Im Beispiel wird eine Tabellenvariable mit einer Identitätsspalte verwendet, die Zeilen in der Tabellenvariablen werden durchlaufen, und für jede Zeile, die mit der Bedingung übereinstimmt, wird eine Aktualisierung ausgeführt. Wenn die Bedingung nicht übereinstimmt, wird eine Einfügung vorgenommen.
Hier ist die T-SQL-Anweisung MERGE, von der Sie sich wünschen, dass sie in einem nativen Proc unterstützt würde und die das Codebeispiel simuliert.
MERGE INTO dbo.Table1 t
USING @tvp v
ON t.Column1 = v.c1
WHEN MATCHED THEN
UPDATE SET Column2 = v.c2
WHEN NOT MATCHED THEN
INSERT (Column1, Column2) VALUES (v.c1, v.c2);
Hier ist der T-SQL-Code, um diese Problemumgehung umzusetzen und MERGE zu simulieren.
DROP PROCEDURE IF EXISTS dbo.usp_merge1;
go
DROP TYPE IF EXISTS dbo.Type1;
go
DROP TABLE IF EXISTS dbo.Table1;
go
-----------------------------
-- target table and table type used for the workaround
-----------------------------
CREATE TABLE dbo.Table1
(
Column1 INT NOT NULL PRIMARY KEY NONCLUSTERED,
Column2 INT NOT NULL
)
WITH (MEMORY_OPTIMIZED = ON);
go
CREATE TYPE dbo.Type1 AS TABLE
(
c1 INT NOT NULL,
c2 INT NOT NULL,
RowID INT NOT NULL IDENTITY(1,1),
INDEX ix_RowID HASH (RowID) WITH (BUCKET_COUNT=1024)
)
WITH (MEMORY_OPTIMIZED = ON);
go
-----------------------------
-- stored procedure implementing the workaround
-----------------------------
CREATE PROCEDURE dbo.usp_merge1
@tvp1 dbo.Type1 READONLY
WITH
NATIVE_COMPILATION, SCHEMABINDING
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT,
LANGUAGE = N'us_english')
DECLARE @i INT = 1, @c1 INT, @c2 INT;
WHILE @i > 0
BEGIN
SELECT @c1 = c1, @c2 = c2
FROM @tvp1
WHERE RowID = @i;
--test whether the row exists in the TVP; if not, we end the loop
IF @@ROWCOUNT=0
SET @i = 0
ELSE
BEGIN
-- try the update
UPDATE dbo.Table1
SET Column2 = @c2
WHERE Column1 = @c1;
-- if there was no row to update, we insert
IF @@ROWCOUNT=0
INSERT INTO dbo.Table1 (Column1, Column2)
VALUES (@c1, @c2);
SET @i += 1
END
END
END
go
-----------------------------
-- test to validate the functionality
-----------------------------
INSERT dbo.Table1 VALUES (1,2);
go
SELECT N'Before-MERGE' AS [Before-MERGE], Column1, Column2
FROM dbo.Table1;
go
DECLARE @tvp1 dbo.Type1;
INSERT @tvp1 (c1, c2) VALUES (1,33), (2,4);
EXECUTE dbo.usp_merge1 @tvp1;
go
SELECT N'After--MERGE' AS [After--MERGE], Column1, Column2
FROM dbo.Table1;
go
/**** Actual output:
Before-MERGE Column1 Column2
Before-MERGE 1 2
After--MERGE Column1 Column2
After--MERGE 1 33
After--MERGE 2 4
****/
Siehe auch
Migrationsprobleme bei systemintern kompilierten gespeicherten Prozeduren
Von In-Memory OLTP nicht unterstützte Transact-SQL-Konstrukte.