Why is an update in a trigger failing? - sql-server

There are many answers on here about how triggers should work but I wonder is mine unique in that the code runs on insert however the #type variable gets a false answer. If I run the query in isolation with the table reference I get a correct answer returned; it is only as part of the trigger that I get a false.
Part of the query calls a function but again this all works when done in isolation so I am wondering is there something else in my trigger causing it to fail that I would be unaware of?
SQL:
ALTER TRIGGER [dbo].[MPH_I_TEST_GROUP_REQUEST_PRINTS]
ON [dbo].[MPH_PRINT_TEST_QUEUE]
FOR INSERT,UPDATE
AS
DECLARE #V_Refno NUMERIC(10)
DECLARE #V_User_Modif VARCHAR(30)
BEGIN
SET #V_User_Modif = suser_sname()
SELECT #V_Refno = tgreq_refno FROM inserted
--> Get details of test type
DECLARE #car_sponts VARCHAR(8000)
DECLARE #type VARCHAR(50)
SET #type = 'blank'
SELECT #car_sponts = CONVERT(VARCHAR(8000),sypro.long_value)
FROM
system_profiles sypro (NOLOCK)
WHERE
sypro.code = 'MPH_CARD_PRT_SPONTS'
AND (sypro.archv_flag = 'N' OR sypro.archv_flag IS NULL)
--> Update type based on tests ordered
SELECT
#type = CASE WHEN COUNT(*) > 0 THEN 'CARDIO' ELSE 'type fail' END --> Does the request belong in a service point noted in system profile MPH_CARD_PRT_SPONTS
FROM
test_group_requests tgreq (NOLOCK)
INNER JOIN
test_form_requests tfreq (NOLOCK) ON tgreq.tgreq_refno = tfreq.tgreq_refno
INNER JOIN
test_requests tereq (NOLOCK) ON tfreq.tfreq_refno = tereq.tfreq_refno
INNER JOIN
test_definitions tstdf (NOLOCK) ON tereq.tstdf_refno = tstdf.tstdf_refno
INNER JOIN
test_locations tstlc (NOLOCK) ON tstlc.tstdf_refno = tstdf.tstdf_refno
WHERE
tgreq.tgreq_refno IN (SELECT tgreq_refno FROM inserted)
AND (tstlc.archv_flag = 'N' OR tstlc.archv_flag IS NULL)
AND tstlc.spont_refno IN
(
SELECT DISTINCT spont.spont_refno FROM service_points spont (NOLOCK) WHERE (spont.archv_flag = 'N' OR spont.archv_flag IS NULL) AND spont.code IN (SELECT Item FROM [dbo].[MPH_PARSELIST](#car_sponts))
)
--> Update test type to print queue
UPDATE mph_print_test_queue
SET mph_print_test_queue.type = 'updated ' + #type
FROM
inserted,mph_print_test_queue
WHERE
mph_print_test_queue.tgreq_refno = inserted.tgreq_refno
END
So currently all records get a type of 'updated type fail' even when they meet the criteria for 'cardio' to be inserted/updated.
Thanks in advance.
Phil.
Tried this update also:
UPDATE mph_print_test_queue
SET mph_print_test_queue.type = 'updated cardio'
FROM
inserted,test_group_requests tgreq (NOLOCK)
INNER JOIN
test_form_requests tfreq (NOLOCK) ON tgreq.tgreq_refno = tfreq.tgreq_refno
INNER JOIN
test_requests tereq (NOLOCK) ON tfreq.tfreq_refno = tereq.tfreq_refno
INNER JOIN
test_definitions tstdf (NOLOCK) ON tereq.tstdf_refno = tstdf.tstdf_refno
INNER JOIN
test_locations tstlc (NOLOCK) ON tstlc.tstdf_refno = tstdf.tstdf_refno
WHERE
tgreq.tgreq_refno = inserted.tgreq_refno
AND (tstlc.archv_flag = 'N' OR tstlc.archv_flag IS NULL)
AND tstlc.spont_refno IN
(
SELECT DISTINCT spont.spont_refno FROM service_points spont (NOLOCK) WHERE (spont.archv_flag = 'N' OR spont.archv_flag IS NULL) AND spont.code IN (SELECT Item FROM [dbo].[MPH_PARSELIST](#car_sponts))
)

I finally got the light bulb moment on my way home. Don't link the update to inserted table but just batch update according to matching records.
Sorry for not getting this before posting. Long day.

Related

How to update data in sql avoiding while loop for better performance

I am updating data in while loop (in stored procedure) which is killing the performance badly. Is there any alternate (best) solution with relatively better performance while updating table.
I have read about CTE but not able to transform in my current problem
WHILE (#Counter <= (SELECT COUNT(id) FROM #TopicsIds))
BEGIN
SELECT #CurrentTopicId = TopicId
FROM #TopicsIds
WHERE id = #Counter;
UPDATE #Modules
SET TopicId = #CurrentTopicId
WHERE id = #Counter;
SET #Counter = #Counter + 1;
END;
UPDATE m
SET TopicId = t.TopicId
FROM #Modules m
JOIN #TopicsIds t ON m.Id = t.Id
Why to use loop for update, use direct update query like
update a set a.TopicId = b.TopicId
from #Modules as a
inner join #TopicsIds as b on a.id = b.id

Update row with values from select on condition, else insert new row

I'm need to run a calculation for month every day. If the month period, exists already, I need to update it, else I need to create a new row for the new month.
Currently, I've written
declare #period varchar(4) = '0218'
DECLARE #Timestamp date = GetDate()
IF EXISTS(select * from #output where period=#period)
/* UPDATE #output SET --- same calculation as below ---*/
ELSE
SELECT
#period AS period,
SUM(timecard.tworkdol) AS dol_local,
SUM(timecard.tworkdol/currates.cdrate) AS dol_USD,
SUM(timecard.tworkhrs) AS hrs,
#Timestamp AS timestamp
FROM dbo.timecard AS timecard
INNER JOIN dbo.timekeep ON timecard.ttk = timekeep.tkinit
INNER JOIN dbo.matter with (nolock) on timecard.tmatter = matter.mmatter
LEFT JOIN dbo.currates with (nolock) on matter.mcurrency = currates.curcode
AND currates.trtype = 'A'
AND timecard.tworkdt BETWEEN currates.cddate1
AND currates.cddate2
WHERE timekeep.tkloc IN('06','07') AND
timecard.twoper = #period
SELECT * FROM #output;
How can simply update my row with the new data from my select.
Not sure what RDBMS are you using, but in SQL Server something like this would update the #output table with the results of the SELECT that you placed in the ELSE part:
UPDATE o
SET o.dol_local = SUM(timecard.tworkdol),
SET o.dol_USD = SUM(timecard.tworkdol/currates.cdrate),
SET o.hrs = SUM(timecard.tworkhrs),
set o.timestamp = #Timestamp
FROM #output o
INNER JOIN dbo.timecard AS timecard ON o.period = timecard.twoper
INNER JOIN dbo.timekeep ON timecard.ttk = timekeep.tkinit
INNER JOIN dbo.matter with (nolock) on timecard.tmatter = matter.mmatter
LEFT JOIN dbo.currates with (nolock) on matter.mcurrency = currates.curcode
AND currates.trtype = 'A'
AND timecard.tworkdt BETWEEN currates.cddate1
AND currates.cddate2
WHERE timekeep.tkloc IN('06','07') AND
timecard.twoper = #period
Also, I think you want to do an INSERT in the ELSE part, but you are doing just a SELECT, so I guess you should fix that too
The answer to this will vary by SQL dialect, but the two main approaches are:
1. Upsert (if your DBMS supports it), for example using a MERGE statement in SQL Server.
2. Base your SQL on an IF:
IF NOT EXISTS (criteria for dupes)
INSERT INTO (logic to insert)
ELSE
UPDATE (logic to update)

Pros and Cons putting all the logic in Stored Procedure (SQL Server) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I just join new organization. They like to put all the logic in stored procedure?
May I know is it a good practice in Software Development.
In addition, I found some of stored procedure having some performance issue when increase number of user. For example, it takes some time to run the following stored procedure.
Next, it it good to have multiples join in a stored procedure like following.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[USP_230_GetMRPByBatch]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[USP_230_GetMRPByBatch]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[USP_230_GetMRPByBatch]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql #statement = N'CREATE PROCEDURE [dbo].[USP_230_GetMRPByBatch] AS'
END
GO
ALTER PROCEDURE [dbo].[USP_230_GetMRPByBatch]
#DIST_CD NVARCHAR(20),
#CUST_CD NVARCHAR(20),
#WHS_CD NVARCHAR(20),
#PRD_CD NVARCHAR(20),
#BILL_METHOD CHAR(1),
#INV_KEY NVARCHAR(50) = ''
AS
--2017-06-30 Chuah - Add Available stock summary from INVT_MASTER
--2018-01-02 Chuah - Add parameter #INV_KEY, need to consider allocated stock for invoice.
BEGIN
SET NOCOUNT ON;
DECLARE #COUNTRY_DT DATETIME
SET #COUNTRY_DT = dbo.GetCountryDate()
IF OBJECT_ID('tempdb..#BATCH_LOTEXP_PERIOD') IS NOT NULL
DROP TABLE #BATCH_LOTEXP_PERIOD
-- Get Batch Exclusion Expiry period
SELECT #PRD_CD AS PRD_CD, E.LOTEXP_IND, E.LOTEXP_MTH,
CASE B.REF_VALUE3 WHEN 0 THEN 0
ELSE ISNULL(J.LOTEXP_DAY,0) END 'LOTEXP_DAY'
INTO #BATCH_LOTEXP_PERIOD
FROM MST_CUSTOPTION AS E
INNER JOIN SET_REF B ON B.DIST_CD = #DIST_CD AND B.REF_TYPE = 'G_WAREHOUSE' AND B.REF_PARAM = #WHS_CD AND B.REF_VALUE2 = 'Y' AND B.REF_VALUE3 = '1'
OUTER APPLY (
SELECT TOP 1 C.LOTEXP_DAY
FROM MST_LOTEXP C
INNER JOIN MST_CUSTATTR D ON D.CUST_CD = #CUST_CD AND D.SYNCOPERATION <> 'D'
INNER JOIN VW_PRD I ON I.PRDCAT_CD = #PRD_CD
WHERE C.CUSTHIER_LEVEL = D.CUSTHIER_LEVEL AND C.CUSTHIER_CD = D.CUSTHIER_CD
AND C.PRDCAT_LEVEL = I.PRDCAT_LEVEL AND C.PRDCAT_CD = I.PRDCAT_CD
AND C.SYNCOPERATION <> 'D'
ORDER BY CAST(C.PRDCAT_LEVEL AS INT) DESC
) AS J
WHERE E.CUST_CD = #CUST_CD AND E.SYNCOPERATION <> 'D'
GROUP BY E.LOTEXP_IND, E.LOTEXP_MTH, B.REF_VALUE3, J.LOTEXP_DAY
-- Get Batch Expiry date
IF OBJECT_ID('tempdb..#BATCH_EXPIRY') IS NOT NULL
DROP TABLE #BATCH_EXPIRY
SELECT A.PRD_CD,
CASE A.LOTEXP_IND WHEN 1 THEN (CASE A.LOTEXP_MTH WHEN 0
THEN CONVERT(VARCHAR(10), DATEADD(DAY,A.LOTEXP_DAY,CONVERT(VARCHAR(10),#COUNTRY_DT,120)),120)
ELSE CONVERT(VARCHAR(10),DATEADD(MONTH,A.LOTEXP_MTH,CONVERT(VARCHAR(10),#COUNTRY_DT,120)),120) END)
ELSE CONVERT(VARCHAR(10),DATEADD(DAY,A.LOTEXP_DAY,CONVERT(VARCHAR(10),#COUNTRY_DT,120)),120) END EXPIRY_DT
INTO #BATCH_EXPIRY
FROM #BATCH_LOTEXP_PERIOD AS A
-- Get MRP by batch
SELECT A.MRP, A.STK_AVAILABLE + ISNULL(F.PRD_QTY, 0) AS STK_AVAILABLE, A.AVAILABLE_STK_MAIN + ISNULL(F.PRD_QTY, 0) AVAILABLE_STK_MAIN FROM (
SELECT A.MRP, SUM(A.AVAILABLE_STK) AS STK_AVAILABLE, MAX(E.AVAILABLE_STK) AVAILABLE_STK_MAIN
FROM INVT_BATCH A
INNER JOIN INVT_BIN B ON B.DIST_CD = A.DIST_CD AND B.WHS_CD = A.WHS_CD AND B.BIN = A.BIN AND B.SYNCOPERATION <> 'D'
LEFT OUTER JOIN #BATCH_EXPIRY AS C ON C.PRD_CD = A.PRD_CD
LEFT OUTER JOIN MST_PRDMRP AS D ON D.DIST_CD = A.DIST_CD AND D.PRD_CD = A.PRD_CD AND D.MRP = A.MRP
LEFT OUTER JOIN (
SELECT DIST_CD, WHS_CD, PRD_CD, SUM(AVAILABLE_STK) AVAILABLE_STK FROM INVT_MASTER
WHERE DIST_CD = #DIST_CD AND PRD_CD = #PRD_CD AND WHS_CD = #WHS_CD
GROUP BY DIST_CD, WHS_CD, PRD_CD
) AS E ON E.DIST_CD = A.DIST_CD AND E.PRD_CD = A.PRD_CD AND E.WHS_CD = A.WHS_CD
WHERE A.DIST_CD = #DIST_CD
AND A.WHS_CD = #WHS_CD
and A.PRD_CD = #PRD_CD
AND CONVERT(VARCHAR(10),A.EXPIRY_DT,120) > ISNULL(C.EXPIRY_DT, CONVERT(VARCHAR(10),#COUNTRY_DT,120))
--AND A.AVAILABLE_STK > 0
AND ISNULL(A.ONHOLD_IND,0) = 0
AND A.SYNCOPERATION <> 'D'
AND ISNULL(A.MRP,0) <> 0
AND (#BILL_METHOD = 'A' OR (#BILL_METHOD = 'L' AND D.PRD_CD IS NOT NULL))
GROUP BY A.DIST_CD, A.WHS_CD, A.PRD_CD, A.MRP
) A
LEFT JOIN (
SELECT TAXABLE_PRC, SUM(PRD_QTY * B.CONV_FACTOR_SML) PRD_QTY FROM TXN_INVDTL_BIN A
INNER JOIN MST_PRDUOM B ON A.PRD_CD = B.PRD_CD AND A.UOM_CD = B.UOM_CD AND B.SYNCOPERATION <> 'D'
WHERE INV_KEY = #INV_KEY AND A.PRD_CD = #PRD_CD AND WHS_CD = #WHS_CD
GROUP BY TAXABLE_PRC
) F ON F.TAXABLE_PRC = A.MRP
WHERE A.STK_AVAILABLE + ISNULL(F.PRD_QTY, 0) > 0
DROP TABLE #BATCH_LOTEXP_PERIOD
DROP TABLE #BATCH_EXPIRY
END
GO
I found some of stored procedure having some performance issue when increase number of user
when stored procedures/any code runs slow, you may need to find the cause by seeing wait stats and execution plan.
Also you said, this happens when load is high,then you need to further check which metric is high..Is it CPU,RAM,IO and start your troubleshooting from there

SQL Server : trigger update if not exists

I have the following trigger is causing me grief.
ALTER TRIGGER [dbo].[T_DMS_Factory_I]
ON [dbo].[jobrun]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
IF NOT EXISTS (select * from inserted i
inner join [db2].[dbo].[table2] t2 on t2.JobRunID = i.jobrun_id)
UPDATE [db2].[dbo].[table2]
SET ProdDt = i.jobrun_proddt,
CreateDt = GETDATE(),
JobrunID = i.jobrun_id,
Start = i.jobrun_time,
End = i.jobrun_stachgtm,
Status = i.jobrun_status,
ActiveDuration = i.jobrun_duration,
TotalDuration = i.jobrun_duration
FROM inserted i
INNER JOIN jobmst jm ON jm.jobmst_id = i.jobmst_id
WHERE jm.jobmst_alias = 'blah'
END
The above works fine but it updates ALL the rows with the same data which I don't want. I only want it to update the row where the time is after before the time of the insert from another column called baseEnd
WHERE jm.jobmst_alias = 'blah' AND baseEnd <= i.jobrun_time AND JobRunID IS NOT NULL
That is what I'd imagine should work but it isn't. What am I doing wrong?
Looking at the tables in your code
UPDATE [db2].[dbo].[table2]
SET
....
FROM inserted i
inner join jobmst jm on jm.jobmst_id = i.jobmst_id
where jm.jobmst_alias = 'blah'
shouldn't you have table2 in the FROM Clause if you're going to update matching records in it.
Otherwise you're just getting some records back from the inserted and jobmst tables and firing values from one of them into all the records in table2
That's why it's not working anyway
It's difficult to see quite what the logic you're trying to implement is but this might be what you need
UPDATE t2
SET ProdDt = i.jobrun_proddt,
CreateDt = GETDATE(),
JobrunID = i.jobrun_id,
Start = i.jobrun_time,
End = i.jobrun_stachgtm,
Status = i.jobrun_status,
ActiveDuration = i.jobrun_duration,
TotalDuration = i.jobrun_duration
FROM inserted i
inner join jobmst jm on jm.jobmst_id = i.jobmst_id
inner join [db2].[dbo].[table2] t2 ON t2.baseEnd <= i.jobrun_time
where jm.jobmst_alias = 'blah'

tsql - While Loop issue using temp table

Our DBA has changed a function to be a procedure, so I am amending some of my procedures to cater for this. I've come across a problem with this in one of my procedures where I have a while loop.
I populate my temp table from the new procedure (#DGContol), and then have the following while loop:
SELECT #MinRcd = MIN(RcdNum) FROM #PortfolioDisclosure
SELECT #MaxRcd = MAX(RcdNum) FROM #PortfolioDisclosure
SET #RcdNum = #MinRcd
WHILE #RcdNum <= #MaxRcd
BEGIN
-- Temporarily assign values to variables
SELECT
#PortfolioGroup = PortfolioCode
, #EndDateTime = MaxPositionDate_DetailedDisclosure
FROM #PortfolioDisclosure
WHERE RcdNum = #RcdNum
INSERT INTO #PositionsTable
SELECT
fi.ID_ISIN AS [Fund_ISIN]
, RTRIM(a.acct_id) AS [Internal_Portfolio_Code]
, a.acct_desc AS [Portfolio/Fund_Name]
, CONVERT(CHAR(11),p.as_of_tms,103) AS [Portfolio_Date]
, a.alt_curr_cde AS [Portfolio_Base_Ccy]
, i.iss_desc AS [Security_Description]
, RTRIM(i.pref_iss_id) AS [Security_ID SEDOL/Internal]
, RTRIM(ia.iss_id) AS [Security_ID ISIN]
, i.denom_curr_cde AS [Denomination_Ccy]
, SUM(p.valval_alt_cmb_amt) OVER (PARTITION BY RTRIM(a.acct_id))
AS [Total_Fund_Value]
, p.orig_quantity AS [Shares/Par_Value]
, p.valval_alt_cmb_amt AS [Market_Value]
, p.fld5_rte AS [Pct_of_NAV]
, SUM(CASE WHEN i.issue_cls1_cde = '010' THEN p.valval_alt_cmb_amt ELSE 0 END) OVER (PARTITION BY a.acct_id)
AS [Cash/Cash_Equivalents]
, i.inc_proj_cmb_rte AS [Coupon_Rate]
, CONVERT(CHAR(11),i.mat_exp_dte,103) AS [Maturity_Date]
FROM dw_position_dg AS p
INNER JOIN #DGControl AS dgc -- [M]onthly, [M]ost recent position
ON dgc.DataGrpCtlNum = p.data_grp_ctl_num
INNER JOIN dw_ivw_acct AS a WITH (NOLOCK)
ON a.acct_id = p.acct_id
INNER JOIN dw_issue_dg AS i WITH (NOLOCK)
ON i.instr_id = p.instr_id
LEFT OUTER JOIN dw_issue_alt_id AS ia WITH (NOLOCK)
ON ia.instr_id = i.instr_id
AND ia.id_ctxt_typ = 'ISIN'
INNER JOIN #PortfolioDisclosure AS fi
ON fi.PortfolioCode = p.acct_id
and fi.MaxPositionDate_DetailedDisclosure >= p.as_of_tms
WHERE RTRIM(a.acct_id) NOT IN ( SELECT xref.internal_value FROM dbo.DP_CrossReference as xref
WHERE xref.Codeset_type_id = 10401
AND xref.Originator_id = 'DataVendorPortfolioExclusion')
-- Clear down variable values
SET #PortfolioGroup = NULL
--SET #StartDateTime = NULL
SET #EndDateTime = NULL
-- Move to next record
SET #RcdNum = #RcdNum + 1
END -- END WHILE LOOP
However this returns lots of duplicate records. If I replace the temp table #DGControl with the original function then I get the correct number of records.
I don't really know what the issue would be or how I could re code this while loop so that using the table #DGControl I get the correct number of records. Can anyone help?
Have you compared the output of SELECT * FROM OldFunction(args..) with EXEC NewStoredProcedure args...? If so, does the data returned look the same or has the duplication crept in when the DBA refactored the function to a proc.
If so you may need to de dupe the output from the sp first then run it through your remaining code. In short, if you are using the same arguments for both but they give you different results then you'll need to go back to the DBA.
You aren't using either of your local variables (#PortfolioGroup, #EndDateTime) in this code. It is just inserting the same record set N number of times. Also, I think you can write this as a single select query without using temp tables or while loops and it will make it less confusing.
Thank you for your feedback. i worked out the issue. My code looks like the following now:
BEGIN
SELECT #MinRcd = MIN(RcdNum) FROM #PortfolioDisclosure
SELECT #MaxRcd = MAX(RcdNum) FROM #PortfolioDisclosure
SET #RcdNum = #MinRcd
WHILE #RcdNum <= #MaxRcd
BEGIN
-- Temporarily assign values to variables
SELECT
#PortfolioGroup = PortfolioCode
, #EndDateTime = MaxPositionDate_DetailedDisclosure
FROM #PortfolioDisclosure
WHERE RcdNum = #RcdNum
-- Insert DGControl record into table based on the MaxPositionDate_DetailedDisclosure from Portfolio Disclosure function
INSERT INTO #DGControl
EXEC InfoPortal..usp_Generic_DGControl '', '', #PortfolioGroup, '1', #EndDateTime, #EndDateTime, #PeriodType, 'M', 'POSITION' -- [M]onthly, [M]ost recent position
-- Insert into #PositionsTable
INSERT INTO #PositionsTable
SELECT
fi.ID_ISIN AS [Fund_ISIN]
, RTRIM(a.acct_id) AS [Internal_Portfolio_Code]
, a.acct_desc AS [Portfolio/Fund_Name]
, CONVERT(CHAR(11),p.as_of_tms,103) AS [Portfolio_Date]
, a.alt_curr_cde AS [Portfolio_Base_Ccy]
, i.iss_desc AS [Security_Description]
, RTRIM(i.pref_iss_id) AS [Security_ID SEDOL/Internal]
, RTRIM(ia.iss_id) AS [Security_ID ISIN]
, i.denom_curr_cde AS [Denomination_Ccy]
, SUM(p.valval_alt_cmb_amt) OVER (PARTITION BY RTRIM(a.acct_id))
AS [Total_Fund_Value]
, p.orig_quantity AS [Shares/Par_Value]
, p.valval_alt_cmb_amt AS [Market_Value]
, p.fld5_rte AS [Pct_of_NAV]
, SUM(CASE WHEN i.issue_cls1_cde = '010' THEN p.valval_alt_cmb_amt ELSE 0 END) OVER (PARTITION BY a.acct_id)
AS [Cash/Cash_Equivalents]
, i.inc_proj_cmb_rte AS [Coupon_Rate]
, CONVERT(CHAR(11),i.mat_exp_dte,103) AS [Maturity_Date]
FROM dw_position_dg AS p
INNER JOIN #DGControl AS dgc
ON dgc.DataGrpCtlNum = p.data_grp_ctl_num
INNER JOIN dw_ivw_acct AS a WITH (NOLOCK)
ON a.acct_id = p.acct_id
INNER JOIN dw_issue_dg AS i WITH (NOLOCK)
ON i.instr_id = p.instr_id
LEFT OUTER JOIN dw_issue_alt_id AS ia WITH (NOLOCK)
ON ia.instr_id = i.instr_id
AND ia.id_ctxt_typ = 'ISIN'
INNER JOIN #PortfolioDisclosure AS fi
ON fi.PortfolioCode = p.acct_id
-- Clear down variable values
SET #PortfolioGroup = NULL
--SET #StartDateTime = NULL
SET #EndDateTime = NULL
-- Clear down #DGControl table to allow new record to be inserted
DELETE FROM #DGControl
-- Move to next record
SET #RcdNum = #RcdNum + 1
END -- END WHILE LOOP
Adding the execution of the stored proc usp_Generic_DGControl at the beginning and then clearing it down after each loop stopped the duplication of the records.

Resources