我想比较表中的Distinct sn
from HMI_Temp
to -> 如果存在,我想更新值 - 得到这个语法检查!- 如果不存在,我想将数据插入我已经尝试过这种语法,但我收到以下错误:sn
HMI
sn
sn
HMI_Temp
HMI
无效的列名 'cb'
无效的列名 'lp'
无效的列名 cn
无效的列名 stn
这是我的语法 - 我应该如何重写它来实现我想要的结果?
MERGE INTO HMI AS Target
USING (SELECT DISTINCT sn FROM HMI_Temp) AS Source ON Target.sn = Source.sn
WHEN NOT MATCHED THEN
INSERT (lp, cb, cn, sn, stn) VALUES (Source.lp, Source.cb, Source.cn, Source.sn, Source.stn);
DDL:
CREATE TABLE [dbo].[HMI_Temp]
(
[sID] [int] IDENTITY(1,1) NOT NULL,
stn [float] NULL,
[sn] [nvarchar](255) NULL,
[cn] [nvarchar](max) NULL,
[lp] [nvarchar](max) NULL,
[cb] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[sID] ASC
) WITH
(
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[HMI_Temp] ON
GO
INSERT [dbo].[HMI_Temp] ([sID], stn, [sn], [cn], [lp], [cb])
VALUES (1, 8888, N'Test', N'Test', N'Test123', N'Test456')
VALUES (1, 8888, N'SecondTest', N'SecondTest', N'SecondTest123', N'SecondTest456')
GO
这是我使用的更新语句,但如果不存在,现在将扳手放入其中以进行插入:(
UPDATE y
SET y.lp = x.lp
,y.cb = x.cb
,y.cn = x.cn
FROM HMI y
INNER JOIN HMI_Temp x
ON y.stn = x.stn
AND y.sn = x.sn
AND y.cn = x.cn
这至少是问题的一部分:如果您有两行
HMI_Temp
具有相同的值sn
但cb
(或任何其他列)的值不同,那么 SQL Server 应该选择哪一个?这是一个比
MERGE
恕我直言更好的模式,它有各种各样的问题:这是取最低的行,
sID
但您可能希望以不同的方式对行进行排名,或者在其他四列中的每一列上使用MIN
/MAX
来确定要保留哪一行。从你的问题很难判断。为了避免语法错误,您需要在
USING
子句中包含所有插入到目标表中的列。所以一个语法上有效的合并语句将是:由于您的预期功能包括更新现有行的能力,因此您还需要一个
WHEN MATCHED
子句,将目标表中的所需列设置为源表中的那些值。就像是:然而,正如 Aaron 在他的回答中提到的那样,
MERGE
它充满了其他潜在的问题。我使用了以下最低限度完整、可验证的示例:
数据如下:
合并声明:
结果,发布
MERGE
:如果
dbo.HMI_Temp
表包含非唯一行,如:运行
MERGE
语句时,您会看到以下错误:由于您现在已经澄清您还需要将
cn
列用作唯一性,您也许可以使用此合并语句:注意,我添加
AND Target.cn = Source.cn
到WHERE
子句中。