ADO 更新或插入缺少第二个执行分支的输出插入值
ADO Update Or Insert is missing Output Inserted Value for second Execute Branch
我正在使用带有 SQL Server 2019 和 Delphi 10.4 Update 2 的 TADOQuery
。我正在尝试在一个 SQL 语句中解决更新或插入操作.
我已将列 IndexField
定义为自动递增列。
这是我的(简体)SQL服务器table:
CREATE TABLE [dbo].[Artikel]
(
[SuchBeg] [varchar](25) NULL,
[ArtNr] [varchar](25) NULL,
[IndexField] [bigint] IDENTITY(1,1) NOT NULL,
PRIMARY KEY CLUSTERED ([IndexField] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
简化的SQL语句:
UPDATE Artikel
SET [SuchBeg] = 'TEST',
[ArtNr] = '19904.S'
OUTPUT INSERTED.[IndexField]
WHERE [ArtNr] = '19904.S'
IF @@ROWCOUNT = 0
INSERT INTO Artikel ([SuchBeg], [ArtNr])
OUTPUT Inserted.[IndexField]
VALUES ('TEST', '19904.S');
Delphi 来源:
Query := TADOQuery.Create(nil);
Query.Connection := ADOConnection;
try
Query.SQL.Text := sSqlText;
Query.Open; // not ExecSQL; if Results are expected: Open does the Trick.
Memo1.Lines.Add('Ado Result: '+ Query.RecordCount.ToString + ' ~ ' + Query.Fields[0].AsString);
finally
Query.Free;
end;
如果我点击 SQL 中的“更新部分”,我可以从查询中读取 1 行 1 字段记录集。但是,如果第二个“插入部分”被执行,我不会得到结果(0 行,1 个字段(Bigint)与 0)。
如果我在没有“if Rowcount”的情况下执行“更新”或“插入”。
如果语句在 SQL Server Management Studio 中执行,它会工作,并显示 2 个结果 Windows。前 0 行受影响,第二行具有所需值,1 行受影响。
是否可以一次性完成?
Alternative Upsert Ways 在这里...但我不想成为 SQL 服务器超级英雄。
尝试将输出存储到 table 变量,然后 return 变量。
DECLARE @Output TABLE (IndexField BIGINT);
UPDATE Artikel SET [SuchBeg] = 'TEST', [ArtNr] = '19904.S' OUTPUT INSERTED.[IndexField] INTO @Output WHERE [ArtNr] = '19904.S'
if @@ROWCOUNT = 0
INSERT INTO Artikel ([SuchBeg], [ArtNr]) Output Inserted.[IndexField] INTO @Output VALUES ('TEST', '19904.S');
SELECT * FROM @Output;
如果您只更新一行,您可以使用 OUTPUT
参数。我不确定 Delphi 那边,但 SQL 看起来像这样
Declare @IndexField Bigint;
UPDATE Artikel
SET [SuchBeg] = 'TEST',
@IndexField = [IndexField]
WHERE [ArtNr] = '19904.5'
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Artikel ([SuchBeg], [ArtNr])
VALUES ('TEST', '19904.5');
SET @IndexField = SCOPE_IDENTITY();
END;
SELECT @IndexField;
我必须说,我没有看到将 ArtNr
列更新为相同值的意义
请注意,如果您想让此 ACID 事务符合要求,您将使用以下提示
SET XACT_ABORT ON; -- ensures rollback
BEGIN TRAN;
UPDATE Artikel WITH (UPDLOCK, HOLDLOCK)
SET [SuchBeg] = 'TEST',
@IndexField = [IndexField]
WHERE [ArtNr] = '19904.S'
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Artikel ([SuchBeg], [ArtNr])
VALUES ('TEST', '19904.S');
SET @IndexField = SCOPE_IDENTITY();
END;
COMMIT;
SELECT @IndexField;
我正在使用带有 SQL Server 2019 和 Delphi 10.4 Update 2 的 TADOQuery
。我正在尝试在一个 SQL 语句中解决更新或插入操作.
我已将列 IndexField
定义为自动递增列。
这是我的(简体)SQL服务器table:
CREATE TABLE [dbo].[Artikel]
(
[SuchBeg] [varchar](25) NULL,
[ArtNr] [varchar](25) NULL,
[IndexField] [bigint] IDENTITY(1,1) NOT NULL,
PRIMARY KEY CLUSTERED ([IndexField] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
简化的SQL语句:
UPDATE Artikel
SET [SuchBeg] = 'TEST',
[ArtNr] = '19904.S'
OUTPUT INSERTED.[IndexField]
WHERE [ArtNr] = '19904.S'
IF @@ROWCOUNT = 0
INSERT INTO Artikel ([SuchBeg], [ArtNr])
OUTPUT Inserted.[IndexField]
VALUES ('TEST', '19904.S');
Delphi 来源:
Query := TADOQuery.Create(nil);
Query.Connection := ADOConnection;
try
Query.SQL.Text := sSqlText;
Query.Open; // not ExecSQL; if Results are expected: Open does the Trick.
Memo1.Lines.Add('Ado Result: '+ Query.RecordCount.ToString + ' ~ ' + Query.Fields[0].AsString);
finally
Query.Free;
end;
如果我点击 SQL 中的“更新部分”,我可以从查询中读取 1 行 1 字段记录集。但是,如果第二个“插入部分”被执行,我不会得到结果(0 行,1 个字段(Bigint)与 0)。
如果我在没有“if Rowcount”的情况下执行“更新”或“插入”。
如果语句在 SQL Server Management Studio 中执行,它会工作,并显示 2 个结果 Windows。前 0 行受影响,第二行具有所需值,1 行受影响。
是否可以一次性完成?
Alternative Upsert Ways 在这里...但我不想成为 SQL 服务器超级英雄。
尝试将输出存储到 table 变量,然后 return 变量。
DECLARE @Output TABLE (IndexField BIGINT);
UPDATE Artikel SET [SuchBeg] = 'TEST', [ArtNr] = '19904.S' OUTPUT INSERTED.[IndexField] INTO @Output WHERE [ArtNr] = '19904.S'
if @@ROWCOUNT = 0
INSERT INTO Artikel ([SuchBeg], [ArtNr]) Output Inserted.[IndexField] INTO @Output VALUES ('TEST', '19904.S');
SELECT * FROM @Output;
如果您只更新一行,您可以使用 OUTPUT
参数。我不确定 Delphi 那边,但 SQL 看起来像这样
Declare @IndexField Bigint;
UPDATE Artikel
SET [SuchBeg] = 'TEST',
@IndexField = [IndexField]
WHERE [ArtNr] = '19904.5'
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Artikel ([SuchBeg], [ArtNr])
VALUES ('TEST', '19904.5');
SET @IndexField = SCOPE_IDENTITY();
END;
SELECT @IndexField;
我必须说,我没有看到将 ArtNr
列更新为相同值的意义
请注意,如果您想让此 ACID 事务符合要求,您将使用以下提示
SET XACT_ABORT ON; -- ensures rollback
BEGIN TRAN;
UPDATE Artikel WITH (UPDLOCK, HOLDLOCK)
SET [SuchBeg] = 'TEST',
@IndexField = [IndexField]
WHERE [ArtNr] = '19904.S'
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Artikel ([SuchBeg], [ArtNr])
VALUES ('TEST', '19904.S');
SET @IndexField = SCOPE_IDENTITY();
END;
COMMIT;
SELECT @IndexField;