SQL Server Transaction inside stored procedure - sql

Suppose, i have two tables Product and ProductSales.
Product table has:
ProductID(int)(pk)
Name(varchar2)
UnitPrice(float)
ProductAvailable(int)
ProductSales table has:
ProductSalesID(int)(pk)
ProductID(int)
Quantity(int)
I want to create a transaction inside stored procedure that first checks if the Quantity is less than ProductAvailable. If it is greater then Rollback the transaction else Deduct the Quantity(given by user) from ProductAvailable and also insert into ProductSales table.
how can i solve the scenario using SQL Server

Solution for concurrent updates:
-- Test Data
CREATE TABLE Product (
ProductID int NOT NULL IDENTITY PRIMARY KEY CLUSTERED
,Name varchar(256) NOT NULL
,UnitPrice money NOT NULL
,ProductAvailable int NOT NULL)
CREATE TABLE ProductSales (
ProductSalesID int NOT NULL IDENTITY PRIMARY KEY CLUSTERED
,ProductID int NOT NULL
,Quantity int NOT NULL)
INSERT INTO Product (Name, UnitPrice, ProductAvailable)
VALUES ('Prod1', 5.0, 10)
,('Prod2',6.0, 5)
GO
First variant - MSDN OUTPUT Clause
CREATE PROCEDURE Sale
#ProductID int
,#Quantity int
AS
BEGIN
IF #Quantity <= 0 RETURN -1;
-- atomic operation
UPDATE Product
SET ProductAvailable = ProductAvailable - #Quantity
OUTPUT INSERTED.ProductID, #Quantity INTO ProductSales (ProductID, Quantity)
WHERE ProductID = #ProductID
AND ProductAvailable >= #Quantity;
IF ##ROWCOUNT = 0 RETURN -1;
END
GO
But it has limitation - output_table cannot:
Have enabled triggers defined on it.
Participate on either side of a FOREIGN KEY constraint.
Have CHECK constraints or enabled rules.
Second variant - MSDN Transaction Statements
CREATE PROCEDURE Sale2
#ProductID int
,#Quantity int
AS
BEGIN
DECLARE #ProcID CHAR(36) = NEWID()
,#TranCount Int = ##TranCount
,#ProductAvailable int
,#errorMessage nvarchar(4000)
,#errorSeverity int
,#errorState int
,#ReturnCode int = -1;
IF #Quantity <= 0 RETURN -1;
IF (#TranCount = 0)
BEGIN TRANSACTION;
ELSE
SAVE TRANSACTION #ProcID;
BEGIN TRY
SELECT #ProductAvailable = ProductAvailable
FROM Product WITH (XLOCK, HOLDLOCK)
WHERE ProductID = #ProductID;
-- Record is locked, you can do any checks here
IF #ProductAvailable >= #Quantity
BEGIN
UPDATE Product
SET ProductAvailable = ProductAvailable - #Quantity
WHERE ProductID = #ProductID;
INSERT INTO ProductSales (ProductID, Quantity)
VALUES(#ProductID, #Quantity);
SET #ReturnCode = 1;
END
ELSE
SET #ReturnCode = -1;
IF (#TranCount = 0)
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF (#TranCount = 0)
ROLLBACK TRANSACTION;
ELSE
IF (XACT_STATE() <> -1)
ROLLBACK TRANSACTION #ProcID;
SELECT #errorMessage = 'Error in [Sale2]: ' + ERROR_MESSAGE(), #errorSeverity = ERROR_SEVERITY(), #errorState = ERROR_STATE();
RAISERROR (#errorMessage, #errorSeverity, #errorState);
SET #ReturnCode = -1;
END CATCH
RETURN #ReturnCode;
END
GO
Check result
-- Test
DECLARE #RetCode int
EXEC #RetCode = Sale #ProductID = 1, #Quantity = 7
SELECT #RetCode as RetCode
EXEC #RetCode = Sale2 #ProductID = 1, #Quantity = 2
SELECT #RetCode as RetCode
EXEC #RetCode = Sale #ProductID = 2, #Quantity = 7
SELECT #RetCode as RetCode
GO
SELECT * FROM ProductSales
SELECT * FROM Product
GO

Related

sql linked server Insert statement fails inside the cursor

Insert statement fails inside the cursor when I try to insert values in to SQL linked server.
If I run the same insert statement outside cursor then it works fine. Is there any settings to be done while creating linked server?
Error message:
OLE DB provider "SQL...." for linked server "" returned message "The parameter is incorrect.".
This is my Code Linked Server in Cursor
SET NOCOUNT ON;
DECLARE #SUBCATEGORY_NAME AS VARCHAR(100), #CategoryStatus AS BIT, #BRAND_NAME AS VARCHAR(100), #BrandMasterStatus AS BIT, #BrandManfacturerName AS VARCHAR(MAX), #PRODUCT_NAME VARCHAR(100), #ProductStatus AS BIT,
#ProductIsReturnable AS BIT, #PRINT_ON_RECEIPT AS VARCHAR(40), #TenantId INT, #CreationTime DATETIME2, #ParentId INT, #BAR_CODE_NO AS VARCHAR(40),
#TAX_CODE AS VARCHAR(MAX), #TaxName AS VARCHAR(MAX), #TaxInclusive AS BIT, #TAX_PERCENTAGE AS FLOAT, #TaxStartDateTime DATETIME2, #BUSINESS_TYPE VARCHAR(20);
--PRINT '-------- Product table migration --------';
DECLARE Product_Cursor CURSOR FOR
SELECT
SC.SUBCATEGORY_NAME,CASE WHEN SC.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS CategoryStatus,
BM.BRAND_NAME,CASE WHEN BM.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS BrandMasterStatus,BM.MANUFACTURER AS BrandManfacturerName,
P.PRODUCT_NAME,CASE WHEN P.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS ProductStatus,
CASE WHEN P.RETURNABLE = 'Y' THEN 1 ELSE 0 END AS ProductIsReturnable,
P.PRINT_ON_RECEIPT,
--SubCategoryId,
--BrandId,
--1 AS TaxId,
1 AS TenantId,
GETDATE() AS CreationTime,
0 AS ParentId,
P.BAR_CODE_NO,
TS.TAX_CODE,
TS.TAX_DESC AS TaxName,
CASE WHEN TS.TAX_INCLUDED = '1' THEN 1 ELSE 0 END AS TaxInclusive,
TS.TAX_PERCENTAGE,
TS.EFFECTIVE_DATE AS TaxStartDateTime,
P.BUSINESS_TYPE
FROM CISPROD.dbo.PRODUCT AS P
RIGHT OUTER JOIN CISPROD.dbo.SUBCATEGORY AS SC ON SC.SUBCATEGORY_ID = P.SUBCATEGORY_ID
FULL OUTER JOIN CISPROD.dbo.BRANDMSTR AS BM ON BM.BRANDMSTR_ID = P.BRANDMSTR_ID
FULL OUTER JOIN CISPROD.dbo.TAX_SETUP AS TS ON TS.TAX_CODE = P.TAX_GROUP
OPEN Product_Cursor
FETCH NEXT FROM Product_Cursor
INTO #SUBCATEGORY_NAME,#CategoryStatus,#BRAND_NAME, #BrandMasterStatus, #BrandManfacturerName, #PRODUCT_NAME, #ProductStatus, #ProductIsReturnable,
#PRINT_ON_RECEIPT, #TenantId, #CreationTime,#ParentId,#BAR_CODE_NO,#TAX_CODE, #TaxName, #TaxInclusive, #TAX_PERCENTAGE, #TaxStartDateTime, #BUSINESS_TYPE;
BEGIN TRANSACTION
BEGIN TRY
WHILE ##FETCH_STATUS = 0
BEGIN
--PRINT ' '
--DECLARE #message VARCHAR(MAX)
--SELECT #message = '----- Products CISPROD: ' + #PRODUCT_NAME
--PRINT #message
--Insert Product Categories Table
DECLARE #CategoryId INT
IF ISNULL(#SUBCATEGORY_NAME,'') <>''
BEGIN
---IF NOT EXISTS(SELECT [Name] FROM ProductCategories WHERE ISNULL([Name], '') = ISNULL(#SUBCATEGORY_NAME,''))
IF NOT EXISTS(SELECT [Name] FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories WHERE [Name] = #SUBCATEGORY_NAME)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories([Name],CreationTime,Inactive,ParentId,TenantId) VALUES(#SUBCATEGORY_NAME,#CreationTime,#CategoryStatus,#ParentId,#TenantId)
SELECT #CategoryId = ##IDENTITY
END
ELSE
BEGIN
SELECT #CategoryId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories WHERE [Name] = #SUBCATEGORY_NAME
END
END
--Insert Product Brand Table
DECLARE #BrandId INT
--DECLARE #DefaultBrandId INT
--SET #DefaultBrandId = 1
IF ISNULL(#BRAND_NAME,'') <>''
BEGIN
--IF NOT EXISTS(SELECT BrandName FROM ProductBrands WHERE ISNULL(BrandName,'') = ISNULL(#BRAND_NAME,''))
IF NOT EXISTS(SELECT BrandName FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands WHERE BrandName = #BRAND_NAME)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands(BrandName,ManufacturerName,CreationTime,Inactive) VALUES(#BRAND_NAME,#BrandManfacturerName,#CreationTime,#BrandMasterStatus)
SELECT #BrandId = ##IDENTITY
END
ELSE
BEGIN
SELECT #BrandId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands WHERE BrandName = #BRAND_NAME
END
END
--ELSE
--BEGIN
-- SET #BrandId = #DefaultBrandId
--END
--Insert Tax Table Records
DECLARE #TaxId INT
IF ISNULL(#TAX_CODE,'') <>''
BEGIN
IF NOT EXISTS(SELECT Code FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes WHERE Code = #TAX_CODE)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes(Code,Inactive,IsInclusive,[Name],TaxTypeId,TenantId) VALUES(#TAX_CODE,1,#TaxInclusive,#TaxName,1,#TenantId)
SELECT #TaxId = ##IDENTITY
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.TaxSchedules([Percentage],StartDateTime,TaxId) VALUES(#TAX_PERCENTAGE,#TaxStartDateTime,#TaxId)
END
ELSE
BEGIN
SELECT #TaxId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes WHERE Code = #TAX_CODE
END
END
--Insert Product Table Records
DECLARE #ProductId INT
IF ISNULL(#PRODUCT_NAME,'') <>''
BEGIN
IF (#BUSINESS_TYPE = 'NF')
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Products([Name],Inactive,IsReturnable,PrintName,
ProductBrandId,ProductCategoryId,TaxId,TenantId,CreationTime)
VALUES(#PRODUCT_NAME,#ProductStatus,#ProductIsReturnable,#PRINT_ON_RECEIPT,#BrandId,#CategoryId,#TaxId,#TenantId,#CreationTime)
END
ELSE
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.FuelProducts([Name],Inactive,PrintName,
ProductCategoryId,TaxId,TenantId,CreationTime)
VALUES(#PRODUCT_NAME,#ProductStatus,#PRINT_ON_RECEIPT,#CategoryId,#TaxId,#TenantId,#CreationTime)
END
SELECT #ProductId = ##IDENTITY
END
--Insert Product Barcode Records
IF ISNULL(#BAR_CODE_NO,'') <>''
BEGIN
IF (#BUSINESS_TYPE = 'NF')
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBarcodes(Barcode,Inactive,ProductId)VALUES(#BAR_CODE_NO,#ProductStatus,#ProductId)
END
END
FETCH NEXT FROM Product_Cursor
INTO #SUBCATEGORY_NAME,#CategoryStatus,#BRAND_NAME, #BrandMasterStatus, #BrandManfacturerName, #PRODUCT_NAME, #ProductStatus, #ProductIsReturnable,
#PRINT_ON_RECEIPT, #TenantId, #CreationTime, #ParentId, #BAR_CODE_NO, #TAX_CODE, #TaxName, #TaxInclusive, #TAX_PERCENTAGE, #TaxStartDateTime,#BUSINESS_TYPE
END
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
-- any other logiing or cleanup
END CATCH
IF ##TranCount>0 -- Transaction still open, so must have succeeded. If rolled back, trancount would be 0
COMMIT TRANSACTION
CLOSE Product_Cursor;
DEALLOCATE Product_Cursor;

RAISERROR Dosn't Work Inside CATCH With ROLLBACK TRANSACTION

I created a Stored Procedure to Insert Into 2 Table With Transaction to make sure That Both Inserts Done and I Used TRY and CATCH to Handle The Errors .. The Problem Is In The Catch Statement I Put ROLLBACK TRANS and RAISERROR The RoLLBACK Works But The Procedure Dose not RAISERROR
Here is The Code
ALTER PROC SP_InsertPlot
#PlotName nvarchar(50),
#GrossArea int,
#SectorName Nvarchar(50),
#PlotYear int,
#OwnerName Nvarchar(50),
#Remarks text,
#NumberOfPlants INT,
#NetArea INT,
#Category Nvarchar(50),
#Type Nvarchar(50),
#Variety Nvarchar(50),
#RootStock Nvarchar(50),
#PlantDistance Decimal(18,2)
AS
BEGIN
DECLARE #PlotID INT
SET #PlotID = (SELECT ISNULL(MAX(PlotID),0) FROM Plots) + 1
DECLARE #SectorID INT
SET #SectorID = (SELECT SectorID FROM Sectors WHERE SectorName = #SectorName)
DECLARE #OwnerID INT
SET #OwnerID = ( SELECT OwnerID FROM Owners WHERE OwnerName = #OwnerName)
DECLARE #CategoryID INT
SET #CategoryID = (SELECT CategoryID FROM Categories WHERE CategoryName = #Category)
DECLARE #TypeID INT
SET #TypeID = (SELECT TypeID FROM Types WHERE TypeName = #Type)
DECLARE #VarietyID INT
SET #VarietyID = (SELECT VarietyID FROM Varieties WHERE VarietyName = #Variety)
DECLARE #RootStockID INT
SET #RootStockID = (SELECT RootStockID FROM RootStocks WHERE RootStockName = #RootStock)
DECLARE #PlotDescID INT
SET #PlotDescID = (SELECT ISNULL(MAX(PlotDescID),0) FROM PlotDescriptionByYear) + 1
BEGIN TRY
SET XACT_ABORT ON
SET NOCOUNT ON
IF(SELECT Count(*) FROM Plots WHERE PlotName = #PlotName) = 0
BEGIN
BEGIN TRANSACTION
INSERT INTO Plots (PlotID,PlotName,GrossArea,SectorID,PlantYear,OnwerID,Remarks)
VALUES(#PlotID,#PlotName,#GrossArea,#SectorID,#PlotYear,#OwnerID,#Remarks)
INSERT INTO PlotDescriptionByYear (PlotDescID, PlantYear, NumberOfPlants,PlotID,NetArea,CategoryID,TypeID,VarietyID,RootStockID,PlantDistance)
VALUES(#PlotDescID,YEAR(GETDATE()),#NumberOfPlants,#PlotID -1,#NetArea,#CategoryID,#TypeID,#VarietyID,#RootStockID,#PlantDistance)
COMMIT TRANSACTION
END
END TRY
BEGIN CATCH
IF(XACT_STATE())= -1
BEGIN
ROLLBACK TRANSACTION
RAISERROR('This Plot Is Already Exists !!',11,1)
END
END CATCH
END
By the way i tried to change the Severity and I tried ##TRANCOUNT instead of XACT_STATE and the Same Problem Happens Which is When I Exec Proc and Pass an Existing Data To The Parameters The Transaction Roll back and did not rise the error
Change IF(XACT_STATE())= -1 to IF(XACT_STATE()) <> 0 and your problem will be done.

i want to decrease the quantity field and decrease its number

CREATE PROCEDURE dbo.IssueBook
(
#bookid nvarchar(50),
#ano nvarchar(50),
#mid int,
#librarian varchar(10),
#quantity int
)
AS
declare #cnt int
declare #msg varchar(100)
if not exists( select * from books where bookid = #bookid and quantity = #quantity)
begin
raiserror('Book is not available',16,1);
return;
end;
select #cnt = count(bookid) from issues where mid = #mid;
if ( #cnt >= 2 )
begin
raiserror('Maximum Limit Has Been Reached For Member!',16,1);
return;
end;
begin tran
begin try
update books set quantity =#quantity-1 where bookid= #bookid;
insert into issues values (#bookid, #mid, getdate(), #librarian, #ano);
commit tran
end try
begin catch
rollback tran
/* select #msg = error_message() */
raiserror( 'Unknown Error', 16,1);
end catch
i want to change value of quantity field in sql table how can i do that please help me i tried many things but they are not working i will be very thankful to you...
I think the problem is in this part: set quantity =#quantity-1. If I understand you correctly, it should either be
set quantity = quantity-1 -- Decreease the book quantity by 1
or
set quantity = quantity - #quantity -- Decreease the book quantity by #quantity

T-SQL insert to shopping cart, goes in the worong else - UPDATED

Hi i don't know how to solve this problem
UPDATE
write new sql but same error.
I know the error, when debugging.
In every if and else it does this:
SET #ShoppingCartId = SCOPE_IDENTITY()
INSERT INTO ShoppingCartItems(ShoppingCartId,ProductID, Quantity)
VALUES(#ShoppingCartId, #ProductID, #Quantity)
That is only to happen if the shoppingcart dont exists.
If there is a way to break out of the code after it's done would solve it.
ShoppingCart
ShoppingCartItems
Stored Procedure
IF EXISTS(SELECT ShoppingCart.ShoppingCartId FROM ShoppingCart WHERE
ShoppingCart.ShoppingCartId = #ShoppingCartId)
--if shoppingcart exists
--check if product exists
IF EXISTS(SELECT ShoppingCartItems.Id FROM ShoppingCartItems WHERE ShoppingCartItems.ProductID = #ProductID AND ShoppingCartItems.ShoppingCartId = #ShoppingCartId)
--Om produkten existerar
BEGIN
UPDATE ShoppingCartItems
SET Quantity = Quantity + 1
WHERE ProductID = #ProductID AND ShoppingCartItems.ShoppingCartId = #ShoppingCartId
END
ELSE
--of product dont exists
BEGIN
INSERT INTO ShoppingCartItems(ShoppingCartId,ProductID, Quantity)
VALUES(#ShoppingCartId, #ProductID, #Quantity)
END
ELSE
--if shoppingcart dont exists
--Insert new shoppingcart
INSERT INTO ShoppingCart(UserID, DateAdded)
VALUES(#UserID, GETDATE())
SET #ShoppingCartId = SCOPE_IDENTITY()
INSERT INTO ShoppingCartItems(ShoppingCartId,ProductID, Quantity)
VALUES(#ShoppingCartId, #ProductID, #Quantity)
The results i get is:
First execution
EXEC #return_value = [dbo].[AddShoppingCart]
#ProductID = 1,
#Quantity = 1,
#UserID = NULL,
#ShoppingCartId = NULL
And Second Execution
EXEC #return_value = [dbo].[AddShoppingCart]
#ProductID = 1,
#Quantity = 1,
#UserID = NULL,
#ShoppingCartId = 1
Everyting looks fine here
But i get a error message.
(1 row(s) affected)
Msg 515, Level 16, State 2, Procedure AddShoppingCart, Line 26
Cannot insert the value NULL into column 'ShoppingCartId', table 'MustTest.dbo.ShoppingCartItems'; column does not allow nulls. INSERT fails.
The statement has been terminated.
After 3rd test when i try to insert the second product in the same shoppingcart
EXEC #return_value = [dbo].[AddShoppingCart]
#ProductID = 2,
#Quantity = 1,
#UserID = NULL,
#ShoppingCartId = 1
My result is all wrong, it inserts product 2 two times and the second time with a ShoppingCartId i didn't put in.
I think it's now working
ALTER PROCEDURE [dbo].[AddShoppingCart]
#ProductID int,
#Quantity int,
#UserID nvarchar(128),
#ShoppingCartId int
AS
IF EXISTS(SELECT ShoppingCart.ShoppingCartId FROM ShoppingCart WHERE ShoppingCart.ShoppingCartId = #ShoppingCartId)
--Om kundvagnen existerar
--Kolla om produkten existerar
IF EXISTS(SELECT ShoppingCartItems.Id FROM ShoppingCartItems WHERE ShoppingCartItems.ProductID = #ProductID AND ShoppingCartItems.ShoppingCartId = #ShoppingCartId)
--Om produkten existerar
BEGIN
UPDATE ShoppingCartItems
SET Quantity = Quantity + 1
WHERE ProductID = #ProductID AND ShoppingCartItems.ShoppingCartId = #ShoppingCartId
END
ELSE
--Om inte produkten existerar
BEGIN
INSERT INTO ShoppingCartItems(ShoppingCartId,ProductID, Quantity)
VALUES(#ShoppingCartId, #ProductID, #Quantity)
END
ELSE
--Om Kundvagnen inte existerar
--Insert ny kundvagn
BEGIN
INSERT INTO ShoppingCart(UserID, DateAdded)
VALUES(#UserID, GETDATE())
SET #ShoppingCartId = SCOPE_IDENTITY()
INSERT INTO ShoppingCartItems(ShoppingCartId,ProductID, Quantity)
VALUES(#ShoppingCartId, #ProductID, #Quantity)
END

Merge sql with date condition

I have create merge stored procedures as below, what i am trying to achieve is the following scenario:
Merge the new record if ProductTRN is not exist in ProductList table (complete)
Only Update the ProductList record in where the PU.CreateDate is bigger than CreateDate of target table which is ProductList (Not Complete)
Please advise me how I can achieve the second scenario above, thank you
CREATE PROCEDURE [dbo].[usp_ProductList_Merge]
AS
BEGIN
DECLARE #retValue INT
BEGIN TRY
IF OBJECT_ID('ProductList') IS NOT NULL
BEGIN
BEGIN TRANSACTION MergeConsumerTable
SET NOCOUNT ON;
MERGE dbo.ProductList AS target
USING
( SELECT
PU.ProductTRN,
PU.ProductName,
PU.ProductDescription,
PU.CreateDate
FROM dbo.TmpProductList PU
WHERE PU.ProductTRN = ProductTRN
) AS source (
ProductTRN,
ProductName,
ProductDescription
CreateDate)
ON ( (target.ProductTRN) = LOWER(source.ProductTRN)
)
WHEN MATCHED
THEN
UPDATE SET
ProductTRN= source.ProductTRN
WHEN NOT MATCHED
THEN
INSERT (
ProductTRN,
ProductName,
ProductDescription,
CreateDate
) VALUES
(
source.ProductTRN,
source.ProductName,
source.ProductDescription,
source.CreateDate,
);
DELETE PU
FROM dbo.TmpProductList PU
COMMIT TRANSACTION MergeProductListTable
SET #retValue = 1
SELECT #retValue
END
ELSE
BEGIN
SET #retValue = -1
SELECT #retValue
END
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION MergeProductListTable
DECLARE #ErrorMsg VARCHAR(MAX);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SET #ErrorMsg = ERROR_MESSAGE();
SET #ErrorSeverity = ERROR_SEVERITY();
SET #ErrorState = ERROR_STATE();
SET #retValue = 0
SELECT #retValue
-- SELECT 0 AS isSuccess
END CATCH
END
WITH Source AS (
SELECT ProductTRN
,ProductName
,ProductDescription
,CreateDate
FROM dbo.TmpProductList
)
MERGE ProductList AS Target
USING Source
ON Target.ProductTRN = Source.ProductTRN
WHEN MATCHED
AND Source.CreatedDate > Target.CreatedDate
THEN UPDATE SET
ProductName = Source.ProductName
,ProductDescription = Source.ProductDescription
,CreateDate = Source.CreatedDate
WHEN NOT MATCHED BY TARGET
THEN INSERT (
ProductTRN
,ProductName
,ProductDescription
,CreateDate
)
VALUES (
Source.ProductTRN
,Source.ProductName
,Source.ProductDescription
,Source.CreatedDate
)