有很多问题可以解决这个错误,但我遇到的问题是:
A)我目前正在进行合并(带插入)
B)我没有明确设置标识栏!
我的存储过程(表名和属性混淆):
CREATE TABLE MyTable (
[ID] BIGINT IDENTITY(1, 1) NOT NULL,
[Value] NVARCHAR (256) NOT NULL,
[Property] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [IX_MyTable] UNIQUE NONCLUSTERED ([Value] ASC)
);
CREATE TYPE TempType as Table (
[TempValue] nvarchar(256) NOT NULL,
[TempProperty] nvarchar(256) NOT NULL,
);
GO
CREATE PROCEDURE [Name]
@Source TempType READONLY
AS
BEGIN
MERGE [MyTable] as target
USING (SELECT * FROM @Source) as source (TempValue, TempProperty)
ON (target.Value = source.TempValue)
WHEN MATCH THEN
UPDATE SET Value = source.TempValue, Property = source.TempProperty
WHEN NOT MATCHED THEN
INSERT ([Value], [Property])
VALUES (source.TempValue, source.TempProperty)
OUTPUT deleted.*, $action, inserted.* INTO [MyTable];
END
从我看到的情况来看,我并没有明确指定IDENTITY
列。我虽然指定了UNIQUE
- 约束列。
最后,与错误所说的相反,指定IDENTITY_INSERT ON
不会做任何事情。
编辑:我还应该指定,我在通过C#从.dacpac
部署时遇到此错误。
答案 0 :(得分:0)
我会简单地删除MERGE语句(设计上有很多问题)并使用如下的简单插入语句:
CREATE PROCEDURE [Name]
@Source TempType READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [MyTable] ([Value], [Property])
SELECT s.TempValue, s.TempProperty
FROM @Source s
WHERE EXISTS (SELECT 1
FROM [MyTable]
WHERE Value = s.TempValue)
END
要阅读有关MERGE语句的问题,请查看本文Use Caution with SQL Server's MERGE Statement
由于您已在Merge语句中添加了更新,现在我还要添加更新语句并将更新包装并插入到一个事务中,但我仍然不建议使用merge语句。
CREATE PROCEDURE [Name]
@Source TempType READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
UPDATE T
SET T.[Property] = S.[Property]
FROM [MyTable] T
INNER JOIN @Source s ON T.Value = s.TempValue
INSERT INTO [MyTable] ([Value], [Property])
SELECT s.TempValue, s.TempProperty
FROM @Source s
WHERE NOT EXISTS (SELECT 1
FROM [MyTable]
WHERE Value = s.TempValue)
COMMIT TRANSACTION;
END