Estou querendo comparar o Distinct sn
from HMI_Temp
to sn
na minha tabela HMI
-> se sn
existir, quero atualizar os valores - consegui essa sintaxe CHECK! - se sn
NÃO existir , quero inserir os dados de HMI_Temp
Tentei HMI
esta sintaxe, mas recebo erros de:
Nome de coluna inválido 'cb'
Nome de coluna inválido 'lp' Nome de
coluna inválido cn Nome de
coluna inválido stn
E esta é a minha sintaxe - como devo reescrever isso para obter o resultado desejado?
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
Esta é a instrução de atualização que eu estava usando que funcionou, mas agora jogando uma chave nela para a inserção, se não existir :(
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
Aqui está pelo menos uma parte do problema: se você tiver duas linhas
HMI_Temp
com o mesmo valor,sn
mas valores diferentes paracb
(ou qualquer outra coluna), qual delas o SQL Server deve escolher?Aqui está um padrão melhor do que
MERGE
, IMHO, que tem todos os tipos de problemas :Isso é pegar a linha com a menor
sID
, mas você pode querer classificar as linhas de uma maneira diferente ou usarMIN
/MAX
em cada uma das outras quatro colunas para determinar qual linha você deseja manter. Difícil dizer pela sua pergunta.Para evitar o erro de sintaxe, você precisa incluir todas as colunas da
USING
cláusula que estão sendo inseridas na tabela de destino. Portanto, uma instrução de mesclagem sintaticamente válida seria:Como a funcionalidade pretendida inclui a capacidade de atualizar linhas existentes, você também precisa de uma
WHEN MATCHED
cláusula que defina as colunas desejadas na tabela de destino para esses valores da tabela de origem. Algo como:No entanto, como mencionado por Aaron em sua resposta,
MERGE
está repleto de outros problemas em potencial.Eu usei o seguinte exemplo minimamente completo e verificável :
Os dados se parecem com:
A instrução de mesclagem:
Os resultados, poste
MERGE
:Se a
dbo.HMI_Temp
tabela contiver linhas não exclusivas, como em:Ao executar a
MERGE
instrução, você verá este erro:Como agora você esclareceu que também precisa usar a
cn
coluna como unificador, talvez seja possível usar esta instrução de mesclagem:Observe, eu adicionei
AND Target.cn = Source.cn
àWHERE
cláusula.