fill a Local #temptable in SQL with multiple Table variables - sql

I'm in SQL Server Management Studio 2008 and I would like to Set Multiple OrderIDs to run them through this query. I heard that I would have to use a TempTable but I'm stuck at how to set Multiple Table variables.
This is the original query I use:
DECLARE #OrderID int
DECLARE #Status int
-- FF nummer
SET #OrderID = 134
-- Huidige status
SET #Status = 4
BEGIN TRANSACTION
UPDATE FF_Task
SET tsk_FK_CurrentStatus = NULL
WHERE (tsk_FK_Order = #OrderID)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = NULL
WHERE (ord_PK = #OrderID)
DELETE FROM FF_StatusLog
WHERE (stl_PK IN
(SELECT TOP (1) FF_StatusLog_1.stl_PK
FROM FF_StatusLog AS FF_StatusLog_1 INNER JOIN
FF_Task ON FF_StatusLog_1.stl_FK_Task = FF_Task.tsk_PK
WHERE (FF_Task.tsk_FK_Order = #OrderID)
ORDER BY FF_StatusLog_1.stl_PK DESC))
DELETE
FROM FF_OrderStatusLog
WHERE (osl_Status = #Status) AND (osl_FK_Order = #OrderID)
UPDATE FF_Task
SET
tsk_FK_CurrentStatus = (SELECT TOP (1) FF_StatusLog_1.stl_PK
FROM FF_StatusLog AS FF_StatusLog_1 INNER JOIN
FF_Task ON FF_StatusLog_1.stl_FK_Task = FF_Task.tsk_PK
WHERE (FF_Task.tsk_FK_Order = #OrderID)
ORDER BY FF_StatusLog_1.stl_PK DESC)
WHERE (tsk_FK_Order = #OrderID)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = (SELECT TOP 1 osl_Status FROM
FF_OrderStatusLog WHERE (osl_FK_Order = #OrderID) ORDER BY osl_CreationDateTime DESC)
WHERE (ord_PK = #OrderID)
COMMIT TRANSACTION
Thank you.

You can use table variable or temp table
Also in SQLServer2008+ you can passing table-valued parameters to SPs and UDFs.A table-value parameter allows you to pass rows of data to your SPs and UDFs in tabular format. To create a table-valued parameter you must first create a table type that defines your table structure.
DECLARE #TableOfParemeters TABLE(OrderID int, Status int)
INSERT #TableOfParemeters
VALUES(134, 4),
(135, 5)
BEGIN TRANSACTION
UPDATE FF_Task
SET tsk_FK_CurrentStatus = NULL
WHERE tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = NULL
WHERE ord_PK IN (SELECT OrderID FROM #TableOfParemeters)
;WITH cte AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY stl_PK ORDER BY stl_PK DESC) AS rn
FROM FF_StatusLog stl INNER JOIN FF_Task ff ON stl.stl_FK_Task = ff.tsk_PK
WHERE ff.tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
DELETE cte
WHERE rn = 1
DELETE
FROM FF_OrderStatusLog
WHERE EXISTS (
SELECT 1
FROM #TableOfParemeters t
WHERE osl_Status = t.Status AND osl_FK_Order = t.OrderID
)
;WITH cte AS
(
SELECT stl.stl_PK, ff.tsk_FK_CurrentStatus,
ROW_NUMBER() OVER(PARTITION BY stl_PK ORDER BY stl_PK DESC) AS rn
FROM FF_StatusLog stl INNER JOIN FF_Task ff ON stl.stl_FK_Task = ff.tsk_PK
WHERE ff.tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
UPDATE cte
SET tsk_FK_CurrentStatus = stl_PK
WHERE rn = 1
;WITH cte AS
(
SELECT o.ord_FK_CurrentOrderStatus, l.osl_Status,
ROW_NUMBER() OVER(PARTITION BY osl_Status ORDER BY osl_CreationDateTime DESC) AS rn
FROM FF_Order o INNER JOIN FF_OrderStatusLog l ON o.ord_PK = l.osl_FK_Order
WHERE l.osl_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
UPDATE cte
SET tsk_FK_CurrentStatus = osl_Status
WHERE rn = 1
COMMIT TRANSACTION

Related

How can I optimize this SQL code further to run faster

UPDATE N SET [actType] = 'X'
FROM tableA N
WHERE NOT EXISTS (SELECT 1
FROM tableA O
WHERE O.clientCode = N.clientCode AND
O.[userName] = N.[userName] AND
O.[profile] = N.[profile] AND
O.[rankID] = N.[rankID] - 1
) AND
N.[rankID] NOT IN (SELECT MIN(T.[rankID])
FROM tableA T
WHERE T.[userName] = N.[userName]
)
You can use row_number() with updatable cte :
with cte as (
select N.*, ROW_NUMBER() OVER (PARTITION BY [userName] ORDER BY rankID) AS Seq
from tableA N
)
update c
set c.[actType] = 'X'
from cte c
where seq > 1 and
not exists (SELECT 1
FROM tableA O
WHERE O.clientCode = c.clientCode AND
O.[userName] = c.[userName] AND
O.[profile] = c.[profile] AND
O.[rankID] = c.[rankID] - 1
);
Your syntax suggests SQL Server. So, you can use.

Increment id value in SQL Server

In my SQL I have this query and I want to increase id with this insert that have
I don't want to use identity(1,1)
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0) + 1
FROM dbo.tbl_waredetails AS wd),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
but it send always 2 as id
Try below query
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0)
FROM dbo.tbl_waredetails AS wd)+ (row_number() over (order by wd.wd_id)),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
with cte as
(select (SELECT isnull(MAX(wd.wd_id),0) FROM dbo.tbl_waredetails ) as iden,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
where ROW_NUMBER ( )
OVER ( order by 1 )=1
union all
select c.iden+1,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
join cte as d on 1=1
where ROW_NUMBER ( )
OVER ( order by 1 )!=1
)
INSERT INTO dbo.tbl_waredetails
(
wd_id,
wd_mt_code ,
wd_wa_Id ,
wd_supply ,
wd_description ,
wd_status
)
SELECT iden, dbo.tbl_material.mat_code,#id,supply,NULL,0
FROM CTE

UPDATE FROM is not working with multiple update of same row

I have #Products and #TempProducts tables. I want to Update #Products from #TempProducts.
My code:
DECLARE #Products TABLE(
Id INT,
Name NVARCHAR(255),
Description NVARCHAR(255));
DECLARE #TempProducts TABLE(
RowNumber int,
Id INT,
Name NVARCHAR(255),
Description NVARCHAR(255));
INSERT INTO #Products(Id,Name,Description) VALUES(1,'Name1','Desc1');
INSERT INTO #TempProducts(RowNumber,Id,Name,Description)
VALUES(1,1,'NewName1',NULL);
INSERT INTO #TempProducts(RowNumber,Id,Name,Description)
VALUES(2,1,NULL,'NewDesc1');
INSERT INTO #TempProducts(RowNumber,Id,Name,Description)
VALUES(3,1,NULL,'NewDesc2');
INSERT INTO #TempProducts(RowNumber,Id,Name,Description)
VALUES(4,1,'NewName2',NULL);
WITH TP AS
(
SELECT TOP (100000) RowNumber,Id,Name,DESCRIPTION
FROM #TempProducts
ORDER BY RowNumber ASC
)
UPDATE P
SET Name = ISNULL(TP.Name,P.Name),
Description = ISNULL(TP.Description,P.Description)
FROM #Products P
INNER JOIN TP
ON P.Id = TP.Id
SELECT * FROM #Products
Expected:
Id Name Description
---------------------------
1 NewName2 NewDesc2
But getting:
Id Name Description
---------------------------
1 NewName1 NewDesc1
Note that I am ordering by ORDER BY RowNumber means Update RowNumber1 first then second and so on.
If there are multiple matches, then SQL Server does not specify which gets updated. If you want the last (or first) value updated, then use window functions to find it:
WITH TP AS (
SELECT t.*,
ROW_NUMBER() OVER (PARRTITION BY ID ORDER BY RowNumber DESC) as seqnum
FROM (SELECT TOP (100000) tp.*
FROM #TempProducts ORDER BY RowNumber ASC
) t
)
UPDATE P
SET Name = ISNULL(TP.Name,P.Name),
Description = ISNULL(TP.Description,P.Description)
FROM #Products P INNER JOIN
TP
ON P.Id = TP.Id AND seqnum = 1;
Use caution when specifying the FROM clause to provide the criteria
for the update operation. The results of an UPDATE statement are
undefined if the statement includes a FROM clause that is not
specified in such a way that only one value is available for each
column occurrence that is updated, that is if the UPDATE statement is
not deterministic.
I would do it like this:
UPDATE P SET Name = ISNULL(ca1.Name, P.Name), Description = ISNULL(ca2.Description, P.Description)
FROM #Products P
OUTER APPLY(SELECT TOP 1 Name FROM #TempProducts WHERE ID = p.ID AND Name IS NOT NULL ORDER BY RowNumber DESC) ca1
OUTER APPLY(SELECT TOP 1 Description FROM #TempProducts WHERE ID = p.ID AND Description IS NOT NULL ORDER BY RowNumber DESC) ca2

Update with CTE and row-numbers as sequence or TSQL update query with ROW_NUMBER()

I have a table named Site with columns Name, SiteId and Sequence. I would like to fill the Sequence field with the rownumber. I've tried the following query, but it just doesn't update the records:
WITH RowNumbers AS
(
select SiteId,
RowNum = row_number() OVER ( order by SiteId )
from [Site]
)
UPDATE s
SET s.[Sequence] = r.RowNum
FROM [Site] as s INNER JOIN RowNumbers as r ON s.SiteId = r.Row
What am I doing wrong?
You can update the CTE directly...
WITH RowNumbers AS
(
select *,
RowNum = row_number() OVER ( order by SiteId )
from [Site]
)
UPDATE RowNumbers
SET [Sequence] = RowNum
This works in the same way as an updatable view. I added * to ensure the the updated field comes through, and then updated it directly.
You should join to r.SiteID, not r.Row
WITH RowNumbers AS
(
select SiteId,
RowNum = row_number() OVER ( order by SiteId )
from [Site]
)
UPDATE s
SET s.[Sequence] = r.RowNum
FROM [Site] as s INNER JOIN RowNumbers as r ON s.SiteId = r.SiteID

Find Duplicate Phones using cte by comparing against other groups

I am trying to determine how many duplicate work phones I can find in Group 94 by comparing against all other groups that are active.
Contacts are grouped using GroupId
The ContactTable Only contains ids and NOT Phones
The DetailedContactTable contains phones
The ContactSummaryTable contains Group status
The sql is working by setting rownumber for each duplicate Workphone > 1.
The problem is that is setting the rownumber > 1 for all groups except for 94. I need to know 94 first and foremost. Any idea how I set rownumber > 1 for duplicates in GroupId 94 first?
DECLARE #GroupID Int
SET #GroupID = 94
;WITH cte AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY d.WorkPhone ORDER BY c.id DESC)
AS rownumber
,d.WorkPhone
,c.id
,GroupID
FROM ContactTable c
INNER JOIN DetailedContactTable d
ON c.DetailedContactId = d.id
WHERE c.GroupID IN
(
SELECT id
FROM ContactSummaryTable WHERE id = #GroupID
OR GroupActive = 1
)
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
)
SELECT * FROM cte WHERE rownumber > 1
ORDER BY GroupID;
DECLARE #GroupID INT;
SET #GroupID = 94;
WITH BaseGroup
AS
(
SELECT c.GroupID
,d.WorkPhone
,c.id ContactID
FROM ContactTable c
INNER JOIN DetailedContactTable d ON c.DetailedContactId = d.id
WHERE c.GroupID = #GroupID
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
),
OtherGroups
AS
(
SELECT
d.WorkPhone
FROM ContactTable c
INNER JOIN DetailedContactTable d ON c.DetailedContactId = d.id
WHERE c.GroupID <> #GroupID
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
AND EXISTS (
SELECT *
FROM ContactSummaryTable WHERE id = c.GroupID
AND GroupActive = 1)
)
SELECT a.*
FROM BaseGroup a
INNER JOIN OtherGroups b ON a.WorkPhone = b.WorkPhone
ORDER BY a.WorkPhone
or
SELECT a.*, CASE WHEN b.WorkPhone IS NULL THEN 'no duplicate' ELSE 'duplicate' END [Status]
FROM BaseGroup a
LEFT JOIN OtherGroups b ON a.WorkPhone = b.WorkPhone
ORDER BY a.WorkPhone