SQL Server Forums
Profile | Register | Active Topics | Members | Search | Forum FAQ
 
Register Now and get your question answered!
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Help with complicated merge statement
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

plap
Starting Member

2 Posts

Posted - 09/03/2012 :  11:49:21  Show Profile  Reply with Quote
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


Edited by - plap on 09/03/2012 11:50:07

visakh16
Very Important crosS Applying yaK Herder

India
48106 Posts

Posted - 09/03/2012 :  15:23:03  Show Profile  Reply with Quote
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 - 09/04/2012 :  02:08:12  Show Profile  Reply with Quote
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
Flowing Fount of Yak Knowledge

5152 Posts

Posted - 09/04/2012 :  07:04:01  Show Profile  Reply with Quote
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

India
48106 Posts

Posted - 09/05/2012 :  21:46:11  Show Profile  Reply with Quote
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
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
SQL Server Forums © 2000-2009 SQLTeam Publishing, LLC Go To Top Of Page
This page was generated in 0.06 seconds. Powered By: Snitz Forums 2000