Using SQL MERGE with vars instead of a table - sql

take the following table (a very simplified example):
CREATE TABLE [dbo].[tbl_Order_Lines] (
[LineID] [int] IDENTITY(1, 1) NOT NULL ,
[OrderID] [int] NOT NULL ,
[StockCode] [varchar](20) NOT NULL ,
[Quantity] [smallint] NOT NULL
)
I have a proc that controls insertions into this table, but at one point you come to the infamous "UPSERT" scenario.
Let’s assume my procedure has the following vars:
#OrderID INT ,
#StockCode VARCHAR(20) ,
#Quantity SMALLINT
I currently do as follows:
IF ( NOT EXISTS ( SELECT *
FROM [dbo].[tbl_Order_Lines]
WHERE [OrderID] = #OrderID
AND [StockCode] = #StockCode )
)
INSERT INTO [dbo].[tbl_Order_Lines]
( [OrderID] ,
[StockCode] ,
[Quantity]
)
VALUES ( #OrderID ,
#StockCode ,
#Quantity
)
ELSE
UPDATE [dbo].[tbl_Order_Lines]
SET Quantity = #Quantity
WHERE [OrderID] = #OrderID
AND [StockCode] = #StockCode
My intention is to do away with this old method and use the MERGE statement - however i'm struggling to get my head round the MERGE statement, this is what i have so far:
MERGE dbo.tbl_Order_Lines
USING (
VALUES
( #Quantity
) ) AS Source ( Quantity )
ON dbo.tbl_Order_Lines.OrderID = #OrderID AND StockCode = #StockCode
WHEN MATCHED THEN
UPDATE SET Quantity = source.Quantity
WHEN NOT MATCHED THEN
INSERT (
OrderID ,
StockCode ,
Quantity
) VALUES
( #OrderID ,
#StockCode ,
Source.Quantity
);
My Question(s):
My attempt at this MERGE seems to work - yet it looks VERY messy and confusing - is there a better way of writing this?
How would i modify this MERGE statement to DELETE matching rows (based on OrderID & StockCode) if #Quantity = 0

You could tighten up the last part by using the special $action keyword.
Case $action
When 'INSERT' Then 'OK_ADDED'
When 'UPDATE' Then 'OK_UPDATED'
When 'DELETE' Then 'OK_REMOVED'
End
$action
Is available only for the MERGE statement. Specifies a column of type nvarchar(10) in the OUTPUT clause in a MERGE statement that returns one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE', according to the action that was performed on that row.
Output Clause.

OK, this is what i came up with:
MERGE dbo.tbl_Order_Lines
USING ( VALUES ( #Quantity ) ) AS Source ( Quantity )
ON dbo.tbl_Order_Lines.OrderID = #OrderID AND StockCode = #StockCode
WHEN MATCHED AND #Quantity > 0 THEN
UPDATE SET Quantity = source.Quantity
WHEN MATCHED AND #Quantity <= 0 THEN
DELETE
WHEN NOT MATCHED AND #Quantity > 0 THEN
INSERT (
OrderID ,
StockCode ,
Quantity
)
VALUES
( #OrderID ,
#StockCode ,
Source.Quantity
)
OUTPUT
COALESCE(Inserted.LineID, Deleted.LineID) AS ResultID ,
CASE WHEN Deleted.LineID IS NULL
AND Inserted.LineID IS NOT NULL THEN 'OK_ADDED'
WHEN Deleted.LineID IS NOT NULL
AND Inserted.LineID IS NOT NULL THEN 'OK_UPDATED'
WHEN Deleted.LineID IS NOT NULL
AND Inserted.LineID IS NULL THEN 'OK_REMOVED'
END AS ResultDesc
INTO #tbl_LineChanges ( ResultID, ResultDesc );
Would still love to know if there is a tider way of writing this!

Related

Update multiple latest record on table using loop

CREATE TABLE [dbo].[masterTable]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[CID] [int] NOT NULL,
[PID] [int] NOT NULL,
[Description] [nvarchar](max) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[State] [nchar](20) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT INTO [dbo].[masterTable]
([CID]
,[PID]
,[Description]
,[CreatedOn]
)
VALUES
(189
,186
,'FC1_189'
,GETUTCDATE()),
(189
,186
,'FC2_189'
,DATEADD(D, +1, GETUTCDATE())),
(190
,186
,'FC1_190'
,DATEADD(d, +2, GETUTCDATE())),
(190
,186
,'FC2_190'
,DATEADD(d, +3, GETUTCDATE())),
(191
,186
,'FC1_191'
,DATEADD(d, +4, GETUTCDATE())),
(191
,186
,'FC2_191'
,DATEADD(d, +5, GETUTCDATE()))
I have a table with 6 records I am trying to update the latest created record based on CID and PID data with the state 'Latest data' and other old created on should update state with 'old data' I tried this but for old created on data not working. check the below query.
Explanation: I currently have 6 records based on CID and PID data.
FC2_189 row is the latest record based on createdOn column so, for this row state column should update with 'latest data' and the other record FC1_189 are old records based on created on date, so compared to FC2_189 row this record is old data based on createdon column so state column should update with 'old data'.
same should happen with FC2_190,FC1_190 and FC2_191,FC1_191 data
SELECT Description,
STATE,
CreatedOn,
PID,
CID,
ROW_NUMBER() OVER (
PARTITION BY ContractID ORDER BY CreatedOn DESC
) contractRN
INTO #ControlTable
FROM masterTable
DECLARE #i INT = 1
DECLARE #count INT
SELECT #count = Count(*)
FROM #ControlTable
WHILE #i <= #count
BEGIN
UPDATE masterTable SET State =
CASE WHEN CreatedOn = (SELECT MAX(CreatedOn) FROM masterTable)
THEN 'Latest data'
ELSE 'Old data'
END
SET #i = #i + 1
END
DROP TABLE #ControlTable
You don't need a loop or joins at all. You can simply calculate a row-number inside a CTE, then update the CTE.
WITH cte AS (
SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY PID, CID ORDER BY CreatedOn DESC)
FROM masterTable
)
UPDATE cte
SET State = CASE WHEN rn = 1
THEN 'Latest data'
ELSE 'Old data'
END;

How to Insert Records only if 2+ records are returned?

So I have this fun little loop that looks for duplicate addresses. I finally tweaked to run quite fast, however I can't quite get what I need from it.
Sample Data and Expected Results
Here is the loop:
WHILE #cnt <= #max
BEGIN
SELECT
#customer_id=[customer_id],
#add1 =[add1],
#add2 =[add2],
#add3 =[add3],
#zip =[zip]
FROM #tmpCustomers
WHERE [id] = #cnt
-- Ensures customer_id is not already in the dupeCustomerAddress table
IF NOT EXISTS( SELECT [customer_id] FROM dupeCustomerAddress WHERE [customer_id] = #customer_id )
BEGIN
INSERT INTO dupeCustomerAddress
SELECT
[customer_id],
[address1],
[add1],
[address2],
[add2],
[address3],
[add3],
[zip]
FROM [working_customerAddress]
WHERE
-- Removes the Record used for comparison
-- [customer_id] != #customer_id AND
-- Don't need to include records already processed
[customer_id] > #cnt AND
(
( -- Address Line 1 or 2 matches Comparison Line 1 AND Zip matches
(
( [address1] IS NOT NULL AND [add1] = #add1 ) OR
( [address2] IS NOT NULL AND [add2] = #add1 )
) AND [zip] = #zip
)
OR
( -- Address Line 1 or 2 matches Comparison Line 2 AND Zip matches
(
( [address1] IS NOT NULL AND [add1] = #add2 ) OR
( [address2] IS NOT NULL AND [add2] = #add2 )
) AND [zip] = #zip
)
)
GROUP BY customer_id, add1, add2, add3, address1, address2, address3, zip
HAVING COUNT(customer_id) > 1
END
SET #cnt = #cnt + 1
END
If I remove the GROUP BY and HAVING then it returns every row since #tmpCustomers is just a subset of fields from working_customerAddress. Which makes sense.
If I uncomment [customer_id] != #customer_id then it gives me only the duplicate record info, not the source record info. So if b and c are duplicates of a, I only get b and c but I want a, b and c.
I tried adding the GROUP BY and HAVING but then I get no results at all.
All of the records should be unique since it's just one per customer_id, so the GROUP BY shouldn't be an issue. Maybe the HAVING isn't right.
What am I missing?
I'm running the latest version of MS SQL Server and SSMS

SQL - Split values from one column into two separate columns

I am trying to take the value of column Quantity and split the values where Quantity is less than 500 and put those records into the LessThan500 column, for the records that are greater than 500 into the GreaterThan500 column.
I have a select statement that does this, but the table does not get updated properly
SUM(CASE WHEN Quantity < 500 THEN CAST(( Quantity*10 ) AS INT)
ELSE ''
END) as Quantityx10
, SUM(CASE WHEN Quantity < 500 THEN CAST(( Quantity*10 ) AS INT)
ELSE ''
END) AS '<500'
, '' AS '>=500'
USE FET
-- Create a new template table
IF OBJECT_ID('dbo.FuelSales', 'U') IS NOT NULL
DROP TABLE dbo.FuelSales;
CREATE TABLE FuelSales
(
TransactionType varchar(1) null,
TransactionID int,
CustomerID int null,
TransactionDate date null,
EntryTimeofDay datetime null,
UserTranNumber varchar(15) null,
AircraftNumber varchar(10) null,
CompanyName varchar(40) null,
NumNameCode varchar(30) null,
Description varchar(40) null,
Quantity decimal(18,6) null,
LessThan500 decimal(18, 6) null,
GreaterThan500 decimal(18,6) null,
);
INSERT INTO FuelSales(TransactionType, TransactionID, CustomerID, TransactionDate, EntryTimeofDay,UserTranNumber,AircraftNumber,CompanyName,NumNameCode,Description,Quantity,LessThan500,GreaterThan500)
SELECT ci.TransactionType
, ci.TransactionID
, ci.CustomerID
, ci.TransactionDate
, ci.EntryTimeofDay
, ci.UserTranNumber
, d.AircraftNumber
, c.CompanyName
, d.NumNameCode
, d.Description
, Quantity
FROM [TFBO7].[dbo].[CustInv] ci
INNER JOIN [TFBO7].[dbo].[Cust] c
ON c.CustomerID=ci.CustomerID
INNER JOIN [TFBO7].[dbo].[CustIDet] d
ON ci.TransactionID=d.TransactionID
WHERE ci.TransactionDate between '20180701' and '20180731' and d.TransactionTypeID='1'
I'm not sure why would you do this permanently on the table and not just do the separation as an ad hoc query when needed but assuming it's SQL Server it would go something like this (in the INSERT statement you're already doing):
...
, Quantity
-- 500 has to go somewhere so I put it in the first category
, LessThan500 = CASE WHEN Quantity <= 500 THEN Quantity ELSE NULL END
, GreaterThan500 = CASE WHEN Quantity > 500 THEN Quantity ELSE NULL END
FROM [TFBO7].[dbo].[CustInv] ci
...
You can add a computed column to the table. Just do:
alter table fuelsales add lessthan500 as (case when quantity <= 500 then quantity end);
alter table fuelsales add greaterthan500 as (case when quantity > 500 then quantity end);
This column will appear in the table when you query the table. However, it is not stored and it is "updated" automatically when quantity changes.

How to excecute a stored procedure taking table as argument one by one?

CREATE TYPE [dbo].[JNLOBJLIST] AS TABLE(
[Journal_Master_Id] [int] NULL,
[strTransRefNumber] [varchar](50) NULL,
[dateGLTransDate] [date] NULL,
[decGLTransAmount] [decimal](18, 4) NULL,
[strGLTransRemark] [varchar](50) NULL,
[guidCompanybranchId] [uniqueidentifier] NULL,
[intGLAccountId] [int] NULL,
[intFiscalYearId] [int] NULL,
[boolGLIsDebit] [binary](1) NULL,
[strPerson] [varchar](50) NULL,
[inttblReferenceId] [int] NULL,
[decGLTransAmount2] [decimal](18, 4) NULL,
[strJournalmemo] [varchar](50) NULL)
GO
and SP:
CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2]
#LIST [dbo].JNLOBJLIST READONLY
AS
DECLARE #id int
BEGIN
INSERT INTO tbl_GL_Trans_Detailstemp
( trans_ref_number
, GL_trans_date
, GL_trans_amount
, GL_trans_remark
, company_branch_id
, GL_Account_id
, fiscal_year_id
, IsDebit
, Person
, tbl_reference_Id)
SELECT strTransRefNumber
, dateGLTransDate
, decGLTransAmount
, strGLTransRemark
, guidCompanybranchId
, intGLAccountId
, intFiscalYearId
, boolGLIsDebit
, strPerson
, inttblReferenceId FROM #LIST
SET #id = (SELECT MAX(GL_trans_id)
FROM tbl_GL_Trans_Detailstemp)
UPDATE tbl_Gl_account
SET GL_Balance = GL_Balance + (SELECT decGLTransAmount2 FROM #LIST)
WHERE (GL_Account_id = (SELECT intGLAccountId FROM #LIST))
DECLARE #Journal_Master_Id int
DECLARE #Trans_Id int
DECLARE #Amount decimal
DECLARE #Memo varchar(50)
SET #Journal_Master_Id=(SELECT Journal_Master_Id FROM #LIST)
SET #Trans_Id=(#id)
SET #Amount=(SELECT decGLTransAmount FROM #LIST)
SET #Memo=(SELECT strJournalmemo FROM #LIST)
INSERT INTO tbl_Journal_Details
(Journal_Master_Id, Trans_Id, Amount, Memo)
VALUES (#Journal_Master_Id,#Trans_Id,#Amount,#Memo)
END
RETURN
actually after my first insert statement , i need the value of tbl_GL_Trans_Detailstemp's
primary key GL_trans_id to insert it into next table...
So if the type table #LIST has many rows(say 5), i need all the statements to get executed one by one(as a loop works)
But as far i have checked the first insert statement works as a whole at first, then only next statements get excecuted. How can i overcome this?
To be more precise, i need a solution which uses following logic
CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2]
#LIST [dbo].JNLOBJLIST READONLY,
#COUNT int
AS
DECLARE #id int
DECLARE #rowcount int=0
WHILE #rowcount<#COUNT
BEGIN
INSERT INTO tbl_GL_Trans_Detailstemp
( trans_ref_number
, GL_trans_date
, GL_trans_amount
, GL_trans_remark
, company_branch_id
, GL_Account_id
, fiscal_year_id
, IsDebit
, Person
, tbl_reference_Id)
SELECT #rowcount.strTransRefNumber
, #rowcount.dateGLTransDate
, #rowcount.decGLTransAmount
, #rowcount.strGLTransRemark
, #rowcount.guidCompanybranchId
, #rowcount.intGLAccountId
, #rowcount.intFiscalYearId
, #rowcount.boolGLIsDebit
, #rowcount.strPerson
, #rowcount.inttblReferenceId FROM #LIST
SET #id = (SELECT MAX(GL_trans_id)
FROM tbl_GL_Trans_Detailstemp)
UPDATE tbl_Gl_account
SET GL_Balance = GL_Balance + (SELECT #rowcount.decGLTransAmount2 FROM #LIST)
WHERE (GL_Account_id = (SELECT #rowcount.intGLAccountId FROM #LIST))
DECLARE #Journal_Master_Id int
DECLARE #Trans_Id int
DECLARE #Amount decimal
DECLARE #Memo varchar(50)
SET #Journal_Master_Id=(SELECT #rowcount.Journal_Master_Id FROM #LIST)
SET #Trans_Id=(#id)
SET #Amount=(SELECT #rowcount.decGLTransAmount FROM #LIST)
SET #Memo=(SELECT #rowcount.strJournalmemo FROM #LIST)
INSERT INTO tbl_Journal_Details
(Journal_Master_Id, Trans_Id, Amount, Memo)
VALUES (#Journal_Master_Id,#Trans_Id,#Amount,#Memo)
SET #rowcount = #rowcount + 1
END
RETURN
It may be possible to avoid a loop and use the OUTPUT from the first INSERT later on in the query. The example below is based on a guess that #list.strTransRefNumber is UNIQUE. Even if it's not UNIQUE it may still be possible for you to refactor the JOIN in the last INSERT as you know how things are related etc.
CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2]
#list [dbo].JNLOBJLIST READONLY
AS
BEGIN
BEGIN TRAN
DECLARE #inserted TABLE ( id INT NOT NULL, strTransRefNumber VARCHAR(50) NOT NULL )
INSERT INTO tbl_GL_Trans_Detailstemp
( trans_ref_number, GL_trans_date, GL_trans_amount, GL_trans_remark, company_branch_id
, GL_Account_id, fiscal_year_id, IsDebit, Person, tbl_reference_Id )
OUTPUT INSERTED.GL_trans_id, INSERTED.trans_ref_number INTO #inserted
SELECT strTransRefNumber, dateGLTransDate, decGLTransAmount, strGLTransRemark
, guidCompanybranchId, intGLAccountId, intFiscalYearId, boolGLIsDebit
, strPerson, inttblReferenceId
FROM #list
-- refactored it to use a join which i think is what you need here
UPDATE a
SET a.GL_Balance = a.GL_Balance + l.decGLTransAmount2
FROM tbl_Gl_account a
JOIN #list l ON l.intGLAccountId = a.GL_Account_id
INSERT INTO tbl_Journal_Details
(Journal_Master_Id, Trans_Id, Amount, Memo)
SELECT l.Journal_Master_Id, i.id, l.decGLTransAmount, l.strJournalmemo
FROM #list l
JOIN #inserted i ON i.strTransRefNumber = l.strTransRefNumber
COMMIT
END
RETURN

Multiple Table Insert with Merge?

I am trying to insert some rows in a parent/child relationship. How does one accomplish this in SQL?
This would be the base query I'd use to find the info I would be inserting:
SELECT * FROM parentTable p
INNER JOIN childTable c
ON p.ID = c.ParentTableID
WHERE p.PlanID = 123456
What needs to happen is that I insert the ParentTable row first which is really just a copy of the matched row but with a new PlanID and Created Date. Then I take that ParentTable ID from the inserted row and use that for the same process but for the Child Table.
So I need to do in .Net speak at least is where I loop through all parentTable matches and for each match create 1 childTable row.
I was trying to use MERGE and the OUTPUT clause but it seems like I'm maybe using a square peg for a round hole. Would I be better off using a CURSOR of some sorts?
So this is what I have so far based on the answer below. Unfortunately it isn't grabbing the SCOPE_IDENTITY()...is there a trick to it? Because that is returning NULL I get FK errors on the inserts.
USE MemberCenteredPlan
DECLARE #NewPlanID BIGINT;--49727690
DECLARE #OldPlanID BIGINT;--49725211
DECLARE #NewSWReAssID BIGINT;
SET #NewPlanID = 49727690
SET #OldPlanID = 49725211
BEGIN
INSERT INTO tblSocialWorkerReAssessment
SELECT
#NewPlanID
,[Discussed]
,Discussion
,NULL
,NULL
,NULL
,CreatedBy
,GETDATE()
,NULL
,NULL
FROM tblSocialWorkerReAssessment
WHERE PlanID = #OldPlanID
SELECT #NewSWReAssID = SCOPE_IDENTITY();
INSERT INTO tblPlanDomain
SELECT
#NewPlanID
,[DomainTypeID]
,[MemberOutcomes]
,[MemberPreferences]
,[DomainDate]
,[Steps]
,[ClinicalFunctionalConcerns]
,[ReportWageES]
,[ReportWageSSA]
,#NewSWReAssID
,[CreatedBy]
,GETDATE()
,NULL
,NULL
,NEWID()
FROM tblPlanDomain
WHERE planID = #OldPlanID
END
You don't need MERGE and you definitely don't need cursors. And an INSERT (or a MERGE) can only ever affect one table at a time, so you'll need to perform multiple statements anyway. If you are only ever dealing with one plan at a time, you can do this:
DECLARE #NewPlanID INT;
INSERT dbo.ParentTable(cols...)
SELECT cols...
FROM dbo.ParentTable WHERE PlanID = 123456;
SELECT #NewPlanID = SCOPE_IDENTITY();
INSERT dbo.ChildTable(ParentTableID, cols...)
SELECT #NewPlanID, cols...
FROM dbo.ChildTable WHERE PlanID = 123456;
If you need to reference multiple new plans, it gets a little more complicated, and in that case you would need to use MERGE (at the present time, INSERT's composable DML is a little on the light side - you can't reference the source table in the OUTPUT clause).
DECLARE #p TABLE(OldPlanID INT, NewPlanID INT);
MERGE dbo.ParentTable WITH (HOLDLOCK)
USING
(
SELECT ID, cols... FROM dbo.ParentTable
WHERE ID IN (123456, 234567)
) AS src ON src.ID IS NULL
WHEN NOT MATCHED THEN INSERT(cols...)
VALUES(src.cols...)
OUTPUT src.ID, inserted.ID INTO #p;
INSERT dbo.ChildTable(ParentTableID, cols...)
SELECT p.NewPlanID, t.cols...
FROM dbo.ChildTable AS t
INNER JOIN #p AS p
ON t.ParentTableID = p.OldPlanID;
However, you should be very wary about this... I link to several issues and unresolved bugs with MERGE in this answer over on dba.SE. I've also posted a cautionary tip here and several others agree.
I think this is what you're after.
Use Northwind
GO
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
CREATE TABLE #OrderAuditHolder
(
[OriginalOrderID] [int] NOT NULL,
[NewOrderID] [int] NOT NULL,
[CustomerID] [nchar](5) NULL,
[EmployeeID] [int] NULL,
[OrderDate] [datetime] NULL,
[RequiredDate] [datetime] NULL,
[ShippedDate] [datetime] NULL,
[ShipVia] [int] NULL,
[Freight] [money] NULL,
[ShipName] [nvarchar](40) NULL,
[ShipAddress] [nvarchar](60) NULL,
[ShipCity] [nvarchar](15) NULL,
[ShipRegion] [nvarchar](15) NULL,
[ShipPostalCode] [nvarchar](10) NULL,
[ShipCountry] [nvarchar](15) NULL,
)
declare #ExampleOrderID int
select #ExampleOrderID = (select top 1 OrderID from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
print '/#ExampleOrderID/'
print #ExampleOrderID
print ''
insert into dbo.Orders (CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry)
output #ExampleOrderID , inserted.OrderID,inserted.CustomerID,inserted.EmployeeID,inserted.OrderDate,inserted.RequiredDate,inserted.ShippedDate,inserted.ShipVia,inserted.Freight,inserted.ShipName,inserted.ShipAddress,inserted.ShipCity,inserted.ShipRegion,inserted.ShipPostalCode,inserted.ShipCountry
into #OrderAuditHolder
Select
CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry
from dbo.Orders where OrderID = #ExampleOrderID
print '/#OrderAuditHolder/'
Select * from #OrderAuditHolder
print ''
Insert into dbo.[Order Details] ( OrderID , ProductID , UnitPrice , Quantity , Discount )
Select
holder.NewOrderID , od.ProductID , od.UnitPrice , od.Quantity , od.Discount
from #OrderAuditHolder holder
join dbo.[Order Details] od on holder.OriginalOrderID = od.OrderID
/* Note, the "join" is on the OriginalOrderID, but the inserted value is the NewOrderID */
/* below is not needed, but shows results */
declare #MaxOrderID int
select #MaxOrderID = (select MAX(OrderID) from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
select * from dbo.[Order Details] where OrderID = #MaxOrderID order by OrderID desc
/**/
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
SET NOCOUNT OFF