Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Help with complicated merge statement

Author  Topic 

plap
Starting Member

2 Posts

Posted - 2012-09-03 : 11:49:21
Consider the following statement:
MERGE TargetTable AS t
USING (SELECT S1.*,S2.* from SourceTable1 as S1 left outer join SourceTable2 as S2 on S1.joinCol=s2.joinCol) AS s
ON (t.recordID = s.recordID)
WHEN MATCHED THEN
UPDATE ...
WHEN NOT MATCHED THEN
INSERT ...

This will work well. However I would like to add some new columns
To the source join result which depend on the success/failure of the join, by nesting further selects. For example:

MERGE TargetTable AS t
USING (
select *,dbo.MyUDF(newCol1) as ProcessedNewCol1
from (
select *,isNull(S2Col,'defaultColVal') as newCol1
from (SELECT S1.*,S2.* from SourceTable1 as S1 left outer join SourceTable2 as S2 on S1.joinCol=s2.joinCol)
)
) AS s ON (t.recordID = s.recordID)
WHEN MATCHED THEN
UPDATE ...
WHEN NOT MATCHED THEN
INSERT ...

This seems perfectly reasonable however fails with an obscure syntax error.
I have an initial attempt written on the adventureworks database:


sET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

alter PROCEDURE sp_test

BEGIN

SET NOCOUNT ON;

CREATE TABLE #MyTempTable
(FirstName [nvarchar](50) NULL,
LastName [nvarchar](50) NULL,
SubTotal [money] NULL,
TaxAmt [money] NULL,
Freight [money] NULL,
TotalDue [money] NULL,
);

MERGE #MyTempTable AS TARGET
USING (SELECT * ,ISNULL([SubTotal],0) AS NewSubTotal
FROM (
SELECT [C].[FirstName],[C].[LastName], [S].[SubTotal],[S].[TaxAmt],[S].[Freight],[S].[TotalDue]
FROM [Sales].[SalesOrderHeader] AS S
JOIN [Person].[Contact] AS C ON [S].[ContactID] = [C].[ContactID]
WHERE [OrderDate]='2004-07-31'
)
) AS SOURCE (FirstName,LastName,SubTotal,TaxAmt,Freight,TotalDue)
ON (1=0)
WHEN NOT MATCHED THEN
INSERT ([FirstName],[LastName],[SubTotal],[TaxAmt],[Freight],[TotalDue])
VALUES ([SOURCE].[FirstName],[SOURCE].[LastName],[SOURCE].[SubTotal],[SOURCE].[TaxAmt],[SOURCE].[Freight],[SOURCE].[TotalDue])

;


SELECT * FROM #MyTempTable;
DROP TABLE #MyTempTable;


END
GO

I am also aware that this logic can be applied at the insert/update level but this will not work for my real life situation.

Thanks for the help,

Gary

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-09-03 : 15:23:03
quote:
Originally posted by plap

Consider the following statement:
MERGE TargetTable AS t
USING (SELECT S1.*,S2.* from SourceTable1 as S1 left outer join SourceTable2 as S2 on S1.joinCol=s2.joinCol) AS s
ON (t.recordID = s.recordID)
WHEN MATCHED THEN
UPDATE ...
WHEN NOT MATCHED THEN
INSERT ...

This will work well. However I would like to add some new columns
To the source join result which depend on the success/failure of the join, by nesting further selects. For example:

MERGE TargetTable AS t
USING (
select *,dbo.MyUDF(newCol1) as ProcessedNewCol1
from (
select *,isNull(S2Col,'defaultColVal') as newCol1
from (SELECT S1.*,S2.* from SourceTable1 as S1 left outer join SourceTable2 as S2 on S1.joinCol=s2.joinCol)
)
) AS s ON (t.recordID = s.recordID)
WHEN MATCHED THEN
UPDATE ...
WHEN NOT MATCHED THEN
INSERT ...

This seems perfectly reasonable however fails with an obscure syntax error.
I have an initial attempt written on the adventureworks database:


sET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

alter PROCEDURE sp_test

BEGIN

SET NOCOUNT ON;

CREATE TABLE #MyTempTable
(FirstName [nvarchar](50) NULL,
LastName [nvarchar](50) NULL,
SubTotal [money] NULL,
TaxAmt [money] NULL,
Freight [money] NULL,
TotalDue [money] NULL,
);

MERGE #MyTempTable AS TARGET
USING (SELECT * ,ISNULL([SubTotal],0) AS NewSubTotal
FROM (
SELECT [C].[FirstName],[C].[LastName], [S].[SubTotal],[S].[TaxAmt],[S].[Freight],[S].[TotalDue]
FROM [Sales].[SalesOrderHeader] AS S
JOIN [Person].[Contact] AS C ON [S].[ContactID] = [C].[ContactID]
WHERE [OrderDate]='2004-07-31'
)AS T
) AS SOURCE (FirstName,LastName,SubTotal,TaxAmt,Freight,TotalDue)
ON (1=0)
WHEN NOT MATCHED THEN
INSERT ([FirstName],[LastName],[SubTotal],[TaxAmt],[Freight],[TotalDue])
VALUES ([SOURCE].[FirstName],[SOURCE].[LastName],[SOURCE].[SubTotal],[SOURCE].[TaxAmt],[SOURCE].[Freight],[SOURCE].[TotalDue])

;


SELECT * FROM #MyTempTable;
DROP TABLE #MyTempTable;


END
GO

I am also aware that this logic can be applied at the insert/update level but this will not work for my real life situation.

Thanks for the help,

Gary




First look itself implies you've a missing alias

also didnt understand purpose of trivial unmatched condition!

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

plap
Starting Member

2 Posts

Posted - 2012-09-04 : 02:08:12
Thanks Visakah that solved it. I thought aliases were always optional. The unmatched condition is just for testing purposes.
Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-09-04 : 07:04:01
In the example you posted, the syntax error is due to the need to alias the inner subquery - see in red below:
CREATE TABLE #MyTempTable
(FirstName [nvarchar](50) NULL,
LastName [nvarchar](50) NULL,
SubTotal [money] NULL,
TaxAmt [money] NULL,
Freight [money] NULL,
TotalDue [money] NULL,
);

MERGE #MyTempTable AS TARGET
USING (SELECT * ,ISNULL([SubTotal],0) AS NewSubTotal
FROM (
SELECT [C].[FirstName],[C].[LastName], [S].[SubTotal],[S].[TaxAmt],[S].[Freight],[S].[TotalDue]
FROM [Sales].[SalesOrderHeader] AS S
JOIN [Person].[Contact] AS C ON [S].[ContactID] = [C].[ContactID]
WHERE [OrderDate]='2004-07-31'
) AS s
) AS SOURCE (FirstName,LastName,SubTotal,TaxAmt,Freight,TotalDue)
ON (1=0)
WHEN NOT MATCHED THEN
INSERT ([FirstName],[LastName],[SubTotal],[TaxAmt],[Freight],[TotalDue])
VALUES ([SOURCE].[FirstName],[SOURCE].[LastName],[SOURCE].[SubTotal],[SOURCE].[TaxAmt],[SOURCE].[Freight],[SOURCE].[TotalDue])

;
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-09-05 : 21:46:11
quote:
Originally posted by plap

Thanks Visakah that solved it. I thought aliases were always optional. The unmatched condition is just for testing purposes.



nope...not at all true for derived tables



------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page
   

- Advertisement -