在SQL合并之前从源表设置值

时间:2014-01-20 18:45:33

标签: sql-server tsql merge sql-server-2012

这就是我梦寐以求的事情,我强调做梦。这很可能是不可能的。

我想做的事情(以我能描述的最佳方式)是使用源表中的数据在merge语句中设置变量。这些变量(例如下面的示例)将在与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

修改 我认为@ 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' (一个丑陋的字符串,从日期时间转换成来自源表的PrintDateTime'。这需要与票证类型类似地设置,但显然这不是一个案例场景。是否有类似的语法包括类似的东西这在选择中也是如此? 再次感谢。

1 个答案:

答案 0 :(得分:0)

SQL Server允许在merge语句中使用变量,但如果我正确理解了您的需求,则可以在不使用变量的情况下执行此操作。我建议将源表转换为行逻辑所在的查询。

以下是我改变事物的方式:

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

我认为这应该能满足你的需求。如果我误解了事情,请告诉我。