2014-01-20 2 views
1

Вот что я мечтаю делать, и я подчеркиваю сновидение. Это, возможно, невозможно.Установить значения из исходной таблицы до слияния SQL

То, что я хочу сделать (наилучшим образом я могу описать его), - это установить переменные в оператор слияния, используя данные из исходной таблицы. Эти переменные, такие как пример ниже, будут обрабатывать исходные данные перед слиянием с таблицей Target. Можно ли это сделать, и если да, то как?

Заранее спасибо.

CREATE PROCEDURE SP_MergeCompetedCasesIntoManifest 

AS BEGIN 

declare @TicketType char(1) 

SET @TicketType = SourceTable.CaseVoided --SourceTable not bound yet, clearly impossible. 

SELECT CASE when @TicketType = 0 
THEN 
    'T' 
ELSE 
    'V' 
END 

MERGE TargetTable AS TargetTable 
USING SourceTable AS SourceTable 
ON TargetTable.CASE_SERIAL_NUMBER = SourceTable.SerialNumber 

WHEN NOT MATCHED BY TARGET 
    THEN INSERT 

( CASE_SERIAL_NUMBER, 
    TICKET_TYPE 
) 

VALUES 

( SourceTable.SerialNumber 
    @TicketType    --Something like this would be nice... 
) 

    WHEN MATCHED 
    THEN UPDATE SET 

TargetTable.TICKET_TYPE = @TicketType;  --Same here... 

END 

EDIT Я думаю, что @ user1178676 находится на правильном пути, к сожалению, после того, как видел его решение, я побежал в другие части этого SP, который нуждался в помощи. Вот еще одна переменная, которую мне нужно установить. Это в основном вывод колонки из исходной таблицы и преобразование ее в строковые поля для соответствия потребностям целевой таблицы.

declare @DateTime datetime 
declare @DateProcessed char(18) 

SET @DateTime = CONVERT(datetime, (select SourceTable.PrintDateTime) 
SET @DateProcessed = CONVERT(char(18), CONVERT(varchar,DATEPART(YYYY, @DateTime)) + '/' + CONVERT(varchar,DATEPART(MM, @DateTime)) 
          + '/' +  CONVERT(varchar,DATEPART(dd, @DateTime)) + ' ' + CONVERT(varchar,DATEPART(HH, @DateTime)) 
          + ':' +  CONVERT(varchar,DATEPART(MI, @DateTime)) + ':' + CONVERT(varchar,DATEPART(SS, @DateTime))) 

Что мне это нужно, чтобы выплюнуть это поле называется «ProductionDate» (уродливая строка преобразуется из DateTime «PrintDateTime» из исходной таблицы. Это будет необходимо установить так же, как тип билета, но очевидно, что это не является сценарием CASE. Есть ли подобный синтаксис, чтобы включить что-то вроде этого в select также? Еще раз спасибо

+0

Вы просто пытаетесь избежать повторения выражения CASE в двух местах в заявлении MERGE? Вы хотите, чтобы он оценивался для каждой обрабатываемой строки? – HABO

+0

@HABO, я хочу оценить каждую строку, да. В принципе, это причудливое слияние одной таблицы в другую таблицу, которая содержит похожие данные, но представляется очень по-разному. Точка SP заключается в том, чтобы избежать использования приложения C# для выполнения преобразования. – bjones

+0

Ну, вы можете заменить это небольшое выражение для форматирования даты следующим образом: 'Convert (Char (10), SourceTable.PrintDateTime, 111) + '' + Convert (Char (8), SourceTable.PrintDateTime, 108)' – HABO

ответ

0

SQL Server позволяет использовать переменные в операторах слияния, но если я правильно понимаю ваши потребности, вы может сделать это без использования переменных. Я бы рекомендовал преобразовать вашу исходную таблицу в запрос, где там живет логика строк.

Вот как я бы изменить положение вещей:

CREATE PROCEDURE SP_MergeCompetedCasesIntoManifest 

AS BEGIN 


MERGE TargetTable AS TargetTable 
USING (
     select SerialNumber, 
     case when CaseVoided = 1 then 'T' else 'V' end as TicketType, 
     CONVERT(char(18), CONVERT(varchar,DATEPART(YYYY, @DateTime)) + '/' + CONVERT(varchar,DATEPART(MM, @DateTime)) 
         + '/' +  CONVERT(varchar,DATEPART(dd, @DateTime)) + ' ' + CONVERT(varchar,DATEPART(HH, @DateTime)) 
         + ':' +  CONVERT(varchar,DATEPART(MI, @DateTime)) + ':' + CONVERT(varchar,DATEPART(SS, @DateTime))) as ProductionDate 
     from SourceTable 

     ) AS SourceTable 
ON TargetTable.CASE_SERIAL_NUMBER = SourceTable.SerialNumber 

WHEN NOT MATCHED BY TARGET 
    THEN INSERT 

( CASE_SERIAL_NUMBER, 
    TICKET_TYPE, 
    ProductionDate 
) 

VALUES 

( SourceTable.SerialNumber, 
    SourceTable.TicketType,    --removed the variable, added the ColumnName of the new source table 
    ProductionDate 
) 

    WHEN MATCHED 
    THEN UPDATE SET 

TargetTable.TICKET_TYPE = SourceTable.TicketType --removed the variable, added the ColumnName of the new source table 
targetTable.ProductionDate = SourceTable.ProductionDate;  

END 

Я думаю, что это должно получить, что вам нужно. Пожалуйста, дайте мне знать, если я не понимаю.

+0

Я думаю, что это сработает для моего первоначального примера. Я отредактировал свое сообщение, чтобы включить другой экземпляр, который, я надеюсь, также можно было бы включить в выбор. Как вы думаете? – bjones

+0

Опять же, я не считаю, что вам нужно использовать переменные здесь. Я изменил оператор слияния, чтобы добавить столбец даты. –

+0

Спасибо @ user1178676. Это привело меня к правильному пути, и мое новое слияние отлично работает! Слияние - потрясающе. – bjones

Смежные вопросы