Слияние в SQL Server 2017

#sql #sql-server #tsql

Вопрос:

Это мой запрос, я хочу объединить данные из источника в пункт назначения (я новичок в SQL Server

 DECLARE @T TABLE(NoContratAdhesion char(8) );
DECLARE @rqt as nvarchar (800000)

SET = 'SELECT * 
       FROM infocentre.[dbo].[TCtrCollRG] as RG
       INNER JOIN SSIS_Temp.dbo.TLID_ADH_RG1_HUM AS RG1 ON RG.NoContratAdhesion = RG1.NoContratAdhesion'

USING (SELECT * FROM SSIS_Temp.dbo.Tmp_CollRG_sans_cle_HUM 
       WHERE Flag_doublons <> '1') AS SOURCE
ON (TARGET.Nocontratadhesion = SOURCE.NoContratAdhesion
AND TARGET.NoAvenant = SOURCE.NoAvenant  
AND TARGET.CodeRG=SOURCE.CodeRG)  

WHEN NOT MATCHED BY TARGET  
    THEN 
        INSERT ([NoContratAdhesion], [NoAvenant], [NoAdherent],
                [CodeProduitCible], [CodeRG], [Optionnel], [Retenu],
                [Retarde], [DateDebutValiditeRG], [DateFinValiditeRG],
                [DateMajRG], [DateInsertPl], [DateMajPl], Date_CHARG_SIAD, FLAG_DELTA)
        VALUES (SOURCE.[NoContratAdhesion], SOURCE.[NoAvenant], NULL, 
                SOURCE.[CodeProduitCible], SOURCE.[CodeRG], SOURCE.[Optionnel], SOURCE.[Retenu],
                SOURCE.[Retarde], SOURCE.[DateDebutValiditeRG], SOURCE.[DateFinValiditeRG],
                SOURCE.[DateMajRG], SOURCE.[DateInsertPl], SOURCE.[DateMajPl], GETDATE(), 'I')

WHEN MATCHED

     THEN UPDATE SET

 TARGET.[NoContratAdhesion]=SOURCE.[NoContratAdhesion]

      ,TARGET.[NoAvenant]=SOURCE.[NoAvenant]

      ,TARGET.[NoAdherent]=NULL

      ,TARGET.[CodeProduitCible]=SOURCE.[CodeProduitCible]

      ,TARGET.[CodeRG]=SOURCE.[CodeRG]

      ,TARGET.[Optionnel]=SOURCE.[Optionnel]

      ,TARGET.[Retenu]=SOURCE.[Retenu]

      ,TARGET.[Retarde]=SOURCE.[Retarde]

      ,TARGET.[DateDebutValiditeRG]=SOURCE.[DateDebutValiditeRG]

      ,TARGET.[DateFinValiditeRG]=SOURCE.[DateFinValiditeRG]

      ,TARGET.[DateMajRG]=SOURCE.[DateMajRG]

      ,TARGET.[DateInsertPl]=SOURCE.[DateInsertPl]

      ,TARGET.[DateMajPl]=SOURCE.[DateMajPl]

         , TARGET.Date_CHARG_SIAD =getdate()

         ,TARGET.FLAG_DELTA='M'

WHEN NOT MATCHED BY SOURCE

    THEN DELETE 

OUTPUT Source.NoContratAdhesion

     INTO @T;             
DELETE infocentre.[dbo].[TCtrCollRG]

WHERE NoContratAdhesion     in (SELECT NoContratAdhesion

                     FROM @T);
                                  select count(*) from infocentre.[dbo].[TCtrCollRG]
 

Я хочу удалить данные, если их нет в пункте назначения, или обновить, если они существуют, я попытался выполнить этот запрос, но возникли ошибки.

Вы можете мне помочь, пожалуйста?

Комментарии:

1. Там нет MERGE , и первое set ничего не устанавливает. Опубликуйте что-нибудь, что действительно компилируется. Не пытайтесь написать один огромный запрос и попытаться скомпилировать его постфактум

2. Я бы посоветовал вам сначала прочитать статью о СЛИЯНИИ — в вашем запросе даже нет ключевого слова MERGE. И динамический SQL не для L»я начинающий в SQL Server»

3. Пожалуйста, прочтите это , чтобы получить несколько советов по улучшению вашего вопроса. Минимальный и полный пример поможет нам помочь вам.

Ответ №1:

nvarchar не допускает длину 800000. Ваша set команда не описывает, какая переменная устанавливается. У вас нет merge предложения, указывающего, какова ваша целевая таблица.

Как минимум, вам нужно изменить это:

 DECLARE @T TABLE(NoContratAdhesion char(8) );
DECLARE @rqt as nvarchar (800000)
set= 'SELECT * from infocentre.[dbo].[TCtrCollRG] as RG
 INNER JOIN SSIS_Temp.dbo.TLID_ADH_RG1_HUM AS RG1 on RG.NoContratAdhesion=RG1.NoContratAdhesion'

USING (SELECT *  from  SSIS_Temp.dbo.Tmp_CollRG_sans_cle_HUM where Flag_doublons <> '1')   AS SOURCE
ON   (TARGET.Nocontratadhesion = SOURCE.NoContratAdhesion

and TARGET.NoAvenant = SOURCE.NoAvenant  and TARGET.CodeRG=SOURCE.CodeRG)  
 

в это:

 DECLARE @T TABLE (NoContratAdhesion char(8));
DECLARE @rqt nvarchar(4000);
set @rqt = '
    SELECT * from infocentre.[dbo].[TCtrCollRG] as RG
    INNER JOIN SSIS_Temp.dbo.TLID_ADH_RG1_HUM AS RG1 on RG.NoContratAdhesion=RG1.NoContratAdhesion
';

merge   @T target
USING   (SELECT * from  SSIS_Temp.dbo.Tmp_CollRG_sans_cle_HUM where Flag_doublons <> '1')   AS SOURCE
ON      TARGET.Nocontratadhesion = SOURCE.NoContratAdhesion
and     TARGET.NoAvenant = SOURCE.NoAvenant  and TARGET.CodeRG=SOURCE.CodeRG  
 

После беглого просмотра я не думаю, что вижу серьезную проблему с остальной частью вашей логики.

Это предполагает, что вы на самом деле пытаетесь слиться с реальной таблицей @T , а не наоборот. В противном merge случае переключите операторы using и.