get columns other than primary key from CHANGETABLE function sql-server - sql-server

I have two table (InvoiceRequests, InvoiceRequestsLineItems), InvoiceRequestsLineItems has InvoiceRequestId as forign key, Qauntity and Rate columns.
My both tables has change tracking enabled.
I'm writing a query that returns the Only the InvoiceRequests that has been changed with there respective Amount(calculated from Qauntity and Rate columns of InvoiceRequestsLineItems).
the scenario is when I update/insert into LineItems I Join the LineItems table and ChangeTable to get the InvoiceRequestId. So I shows customers that 'InvoiceRequest' Amount changed.
But when I delete any LineItems I lost the InvoiceRequestId(foreign key) from that row. Then I cant able to tell the amount has been changed for perticular InvoiceRequests.
Is there any way that ChangeTable function can return other columns(InvoiceRequestId) apart from PrimaryKey(InvoiceRequestLineItemId).
Solution like adding trigger and keep the deleted record in separate table will increase lot of overhead.
Please provide any suggestion, that I can do with minimal changes. Thanks
SELECT
CTIRL.INVOICEREQUESTSID [InvoiceRequestId],
IR.STATUS [Status],
ERIL.[InvoiceRequestAmount],
CAST(0 as BIT) [Deleted]
FROM
(SELECT [IRS].INVOICEREQUESTSID, CTL.SYS_CHANGE_COLUMNS, CTL.sys_change_operation
FROM INVOICEREQUESTLINEITEMS [IRS]
JOIN CHANGETABLE( CHANGES dbo.INVOICEREQUESTLINEITEMS, #ctversion) CTL
ON CTL.INVOICEREQUESTLINEITEMSID = [IRS].INVOICEREQUESTLINEITEMSID
) AS CTIRL
LEFT JOIN dbo.INVOICEREQUESTS IR
ON CTIRL.INVOICEREQUESTSID = IR.INVOICEREQUESTSID
LEFT JOIN (
SELECT
IRLI.INVOICEREQUESTSID,
SUM(
IRLI.QUANTITY * IRLI.RATE + COALESCE(IRLI.TAXAMOUNT, 0)
) [InvoiceRequestAmount]
FROM
INVOICEREQUESTLINEITEMS IRLI
GROUP BY
IRLI.INVOICEREQUESTSID
) AS ERIL
ON ERIL.INVOICEREQUESTSID = RES.InvoiceRequestId
WHERE
(
CHANGE_TRACKING_IS_COLUMN_IN_MASK(5, CTIRL.SYS_CHANGE_COLUMNS) = 1
OR CHANGE_TRACKING_IS_COLUMN_IN_MASK(7, CTIRL.SYS_CHANGE_COLUMNS) = 1
OR CHANGE_TRACKING_IS_COLUMN_IN_MASK(11, CTIRL.SYS_CHANGE_COLUMNS) = 1
OR CTIRL.sys_change_operation = 'D'
OR CTIRL.sys_change_operation = 'I'
)

Related

The multi-part identifier "[column name]" could not be bound in UPDATE of TEMP Table

I am trying to create a stored procedure whereupon I input a (simple for now) query into a temp table, and then replace some of the data with data from a different table based on a key.
Here is the complete code:
CREATE PROCEDURE GetInquiryList
AS
BEGIN
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#Inq ') IS NOT NULL
DROP TABLE #Inq
SELECT i.*,q.QuoteID INTO #Inq FROM Inquiries i left join Quotes q on i.InquiryId = q.InquiryId
WHERE i.YNDeleted = 0
--SELECT * FROM #Inq
UPDATE #Inq
SET j.InquiryCustomerName = c.CustomerName,
j.InquiryCustomerEmail = c.CustomerEmail,
j.InquiryCustomerPhone = c.CustomerPhone1,
j.InquiryBestTimetoCall = c.CustomerBestTimetoCall,
j.InquiryDay = c.customerDay,
j.InquiryNight = c.CustomerNight
SELECT c.CustomerName,
c.CustomerEmail,
c.CustomerPhone1,
c.CustomerBestTimetoCall,
c.customerDay,
c.CustomerNight
FROM Customers c
INNER JOIN #Inq j ON
j.InquiryCustomerID = c.CustomerID
SELECT * FROM #Inq
END
I get the following error:
Msg 4104, Level 16, State 1, Line 15 The multi-part identifier "j.InquiryCustomerName" could not be bound
I get this error for whatever column is placed first after the SET command.
Both query pieces of this work independently (the first select creating the temp table and the joined query at the bottom). The data returned is correct. I have tried using aliases (SELECT c.CustomerName AS Name, ...).
Originally, I used "#Inq i" in the second command, but changed to "j" out of an abundance of caution.
I have also run the command against the original table (substituting the Inquiry table for the temp table #Inq, and that fails as well).
Shortening it to this:
UPDATE #Inq
SET j.InquiryCustomerName = c.CustomerName,
j.InquiryCustomerEmail = c.CustomerEmail,
j.InquiryCustomerPhone = c.CustomerPhone1,
j.InquiryBestTimetoCall = c.CustomerBestTimetoCall,
j.InquiryDay = c.customerDay,
j.InquiryNight = c.CustomerNight
FROM Customers c
INNER JOIN #Inq j ON
j.InquiryCustomerID = c.CustomerID
I get a different error:
Msg 4104, Level 16, State 1, Line 15 The multi-part identifier "j.InquiryCustomerName" could not be bound
I'm sure it's probably something simple,(so simple that I can't find any references in any of my searches).
I'm sure it has something to do with the fact that you can't update the same instance of the table used in the join (I'm going to have to re-join again with a "k" alias). How do I do this?
data from the first query
data from the first query
data from the second select statement on the actual temp table
Here is what I updated the stored procedure to, which works exactly how I need it to:
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#Inq ') IS NOT NULL
DROP TABLE #Inq
SELECT i.* INTO #Inq FROM (
select inquiries.InquiryId,
inquiries.InquiryDateReceived,
inquiries.InquiryCustomerID,
cust.CustomerName as InquiryCustomerName,
cust.CustomerEmail as InquiryCustomerEmail,
cust.CustomerPhone1 as InquiryCustomerPhone,
cust.CustomerBestTimeToCall as InquiryBestTimeToCall,
cust.CustomerDay as InquiryDay,
cust.CustomerNight as InquiryNight,
inquiries.InquiryServiceType,
inquiries.InquiryServiceID,
inquiries.InquiryTimeframe,
inquiries.InquiryProjectDescription,
inquiries.InquiryDateResponded,
inquiries.InquiryCustomerReply,
inquiries.YNMigrated,
inquiries.InquiryDateClosed,
inquiries.YNClosed,
inquiries.YNDeleted
from inquiries inner join dbo.Customers as cust
on inquiries.InquiryCustomerID = cust.CustomerID and inquiries.InquiryCustomerID > 0
UNION ALL
select inquiries.InquiryId,
inquiries.InquiryDateReceived,
inquiries.InquiryCustomerID,
InquiryCustomerName,
InquiryCustomerEmail,
InquiryCustomerPhone,
InquiryBestTimeToCall,
InquiryDay,
InquiryNight,
inquiries.InquiryServiceType,
inquiries.InquiryServiceID,
inquiries.InquiryTimeframe,
inquiries.InquiryProjectDescription,
inquiries.InquiryDateResponded,
inquiries.InquiryCustomerReply,
inquiries.YNMigrated,
inquiries.InquiryDateClosed,
inquiries.YNClosed,
inquiries.YNDeleted
from inquiries WHERE inquiries.InquiryCustomerID = 0
) i
select i.*, q.QuoteID
FROM #Inq i left join dbo.Quotes as q
on i.InquiryId = q.InquiryId
WHERE i.YNDeleted = 0
END
Just stop using this pattern without a really good reason. Here it only appears to create more work for the database engine with no obvious benefit. Your procedure - as posted - has trivially simple queries so why bother with the temp table and the update?
It is also time to start learning and using best practices. Terminate EVERY statement - eventually it will be required. Does order of the rows in your resultset matter? Usually it does and that is only guaranteed when that resultset is produced by a query that includes an ORDER BY clause.
As a developing/debugging short cut, you can harness the power of CTEs to help you build a working query. In this case, you can "stuff" your first query into a CTE and then simply join the CTE to Customers and "adjust" the columns you need in that resultset.
WITH inquiries as (
select inq.*, qt.QuoteID
FROM dbo.Inquiries as inq left join dbo.Quotes as qt
on inq.InquiryId = qt.InquiryId
WHERE inq.YNDeleted = 0
)
select inquiries.<col>,
...,
cust.CustomerName as "InquiryCustomerName",
...
from inquiries inner (? guessing) dbo.Customers as cust
on inquiries.InquiryCustomerID = cust.CustomerID
order by ...
;
Schema names added as best practice. Listing the columns you actually need in your resultset is another best practice. Note I did not do that for the query in the CTE but you should. You can choose to create aliases for your resultset columns as needed. I listed one example that corresponds to your UPDATE attempt.
It is odd and very suspicious that all of the columns you intended to UPDATE exist in the Inquiries table. Are you certain you need to do that at all? Do they actually differ from the related columns in the Customer table? Also odd that the value 0 exists in InquiryCustomerID - suggesting you might have not a FK to enforce the relationship. Perhaps that means you need to outer join rather than inner join (as I wrote). If an outer join is needed, then you will need to use CASE expressions to "choose" which value (the CTE value or the Customer value) to use for those columns.
After learning a lot more about how things get bound to models, and how to further use sql, here is what my stored procedure looks like:
ALTER PROCEDURE [dbo].[GetInquiryList]
#InquiryID int = 0
AS
BEGIN
SET NOCOUNT ON
select i.InquiryId,
i.InquiryDateReceived,
i.InquiryCustomerID,
InquiryCustomerName =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryCustomerName
ELSE c.CustomerName
END,
InquiryCustomerEmail =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryCustomerEmail
ELSE c.CustomerEmail
END,
InquiryCustomerPhone =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryCustomerPhone
ELSE c.CustomerPhone1
END,
InquiryBestTimetoCall =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryBestTimetoCall
ELSE c.CustomerBestTimetoCall
END,
InquiryDay =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryDay
ELSE c.CustomerDay
END,
InquiryNight =
CASE i.InquiryCustomerID
WHEN 0 THEN i.InquiryNight
ELSE c.CustomerNight
END,
i.InquiryServiceType,
i.InquiryServiceID,
i.InquiryTimeframe,
i.InquiryProjectDescription,
i.InquiryDateResponded,
i.InquiryCustomerReply,
i.YNMigrated,
i.InquiryDateClosed,
i.YNClosed,
i.YNDeleted, ISNULL(q.QuoteId,0) AS Quoteid
FROM dbo.Inquiries i
LEFT JOIN dbo.Quotes q ON i.InquiryId = q.InquiryId
LEFT JOIN dbo.Customers c ON i.InquiryCustomerID = c.CustomerId
WHERE i.YNDeleted = 0
END
I'm sure there are additional enhancements that could be made, but avoiding the union is a big savings. Thanks, everyone.

How to update multiple rows in a temp table with multiple values from another table using only one ID common between them?

I am trying to reconcile the IDs in a temp table (top) from another DB table (bottom). Since I only have one ID that's common between the two, I am only getting the top result for all the rows (ReconGlobalRemunerationGrantID) in my temp table. I am aiming to get each of the unique ID and update my temp table as such.
Right now, my update query is simple and I update using the ID common between the 2 tables. Is there a function or another command statement I can use to get the result intended?
update tgrg set ReconGlobalRemunerationGrantID = grg.GlobalRemunerationGrantID from #GlobalRemunerationGrant tgrg
join #GlobalRemuneration tgr on tgr.GlobalRemunerationID = tgrg.GlobalRemunerationID
join DataCore..GlobalRemuneration gr on gr.CompanyID = #CompanyID and gr.FiscalYearID = tgr.FiscalYearID and gr.DirectorDetailID = tgr.DirectorDetailID and tgr.GlobalRoleIDCODE = gr.GlobalRoleID
join DataCore..GlobalRemunerationGrant grg on gr.GlobalRemunerationID = grg.GlobalRemunerationID
Thank you.
Based on the comment - you have 2 values to match on, not just one? e.g., both GlobalRemunerationID and GlobalRemunerationGrantID?
Here's an example using tables 'temptable' and 't1'
UPDATE temptable
SET ReconGlobalRemunerationGrantID = t1.GlobalRemunerationGrantID
FROM temptable
INNER JOIN t1 ON temptable.GlobalRemunerationID = t1.GlobalRemunerationID
AND temptable.GlobalRemunerationGrantID = t1.GlobalRemunerationGrantID
Update below
The below version takes the two data sets
Partitions them by GlobalRemunerationID and orders them by ReconGlobalRemunerationGrantID to get the 'row numbers' (rn)
Joins them on GlobalRemunerationID and rn to get them in order
Key code is below (with slightly different tables than your full set sorry - matches the data set you gave though).
; WITH tgrg AS
(SELECT GlobalRemunerationID, ReconGlobalRemunerationGrantID,
ROW_NUMBER() OVER (PARTITION BY GlobalRemunerationID ORDER BY GlobalRemunerationGrantID) AS rn
FROM #GlobalRemunerationGrant
)
UPDATE tgrg
SET ReconGlobalRemunerationGrantID = tgr.GlobalRemunerationGrantID
FROM tgrg
INNER JOIN
(SELECT GlobalRemunerationID, GlobalRemunerationGrantID,
ROW_NUMBER() OVER (PARTITION BY GlobalRemunerationID ORDER BY GlobalRemunerationGrantID) AS rn
FROM GlobalRemuneration
) AS tgr ON tgrg.GlobalRemunerationID = tgr.GlobalRemunerationID AND tgrg.rn = tgr.rn
A db<>fiddle with the full set is there - note that I changed some of the IDs to demonstrate that it wasn;t using them to match.

SQL Server Table Triggers update an aggregate table-update/insert multiple records

(NOTE: My question is detailed and specific to our system so I will apologize for the length of the explanation before I get to my actual question in advance.)
We have a number of tables that need to have a portion of the data contained therein aggregated to another table.
I have tried, to the best of my ability, to ensure the trigger can handle multiple rows and not just single row transactions:
TRIGGER [dbo].[TR_SavedFiles_PlanLibraryMetrics] on [dbo].[SavedFiles]
AFTER INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON
BEGIN
IF EXISTS (
SELECT m.AccountID, m.PlanLibCode
FROM PlanLibraryMetrics AS m
JOIN PlanLibraryItems AS it
ON m.PlanLibCode = it.PlanLibCode
JOIN inserted AS i
ON m.AccountID = i.AccountID
AND (it.ItemTypeID = i.CISFileID AND it.ItemType = 'FILE')
JOIN Accounts AS a ON i.AccountID = a.AccountID
WHERE a.Status = 0
)
BEGIN
UPDATE PlanLibraryMetrics
SET MetricValue = x.newValue
FROM (SELECT COUNT(s.AccountID) AS newValue, it.PlanLibCode, i.AccountID
FROM SavedFiles AS s
JOIN PlanLibraryItems AS it
ON (s.CISFileID = it.ItemTypeID AND it.ItemType = 'FILE')
JOIN inserted AS i
ON s.AccountID = i.AccountID
AND s.CISFileID = i.CISFileID
Group By PlanLibCode, i.AccountID) AS x
JOIN PlanLibraryMetrics AS m
ON x.PlanLibCode = m.PlanLibCode
AND x.AccountID = m.AccountID
END
ELSE IF EXISTS (
SELECT m.AccountID, m.PlanLibCode
FROM PlanLibraryMetrics AS m
JOIN PlanLibraryItems AS it
ON m.PlanLibCode = it.PlanLibCode
JOIN deleted AS d
ON m.AccountID = d.AccountID
AND (it.ItemTypeID = d.CISFileID AND it.ItemType = 'FILE')
JOIN Accounts AS a ON d.AccountID = a.AccountID
WHERE a.Status = 0
)
BEGIN
UPDATE PlanLibraryMetrics
SET MetricValue = x.newValue
FROM (SELECT COUNT(s.AccountID) AS newValue,it.PlanLibCode, d.AccountID
FROM SavedFiles AS s
RIGHT OUTER JOIN deleted AS d
ON s.AccountID = d.AccountID
AND s.CISFileID = d.CISFileID
JOIN PlanLibraryItems AS it
ON (d.CISFileID = it.ItemTypeID AND it.ItemType = 'FILE')
Group By PlanLibCode, d.AccountID) AS x
JOIN PlanLibraryMetrics AS m
ON x.PlanLibCode = m.PlanLibCode
AND x.AccountID = m.AccountID
END
ELSE IF NOT EXISTS (
SELECT m.AccountID, m.PlanLibCode
FROM PlanLibraryMetrics AS m
JOIN PlanLibraryItems AS it ON m.PlanLibCode = it.PlanLibCode
JOIN inserted AS i
ON m.AccountID = i.AccountID
AND (it.ItemTypeID = i.CISFileID AND it.ItemType = 'FILE')
JOIN Accounts AS a ON i.AccountID = a.AccountID
WHERE a.Status = 0
)
BEGIN
INSERT INTO PlanLibraryMetrics
SELECT i.AccountID, it.PlanLibCode, COUNT(s.AccountID)
FROM SavedFiles AS s
JOIN PlanLibraryItems AS it
ON (s.CISFileID = it.ItemTypeID AND it.ItemType = 'FILE')
JOIN inserted AS i
ON s.AccountID = i.AccountID
AND s.CISFileID = i.CISFileID
Group By PlanLibCode, i.AccountID
END
END
And it appears to work, until we get to a system we have in place to "merge" accounts whereby all the records from the old account(s) have their accountid's changed to the primary account.
The behavior I am trying to accomplish is to update any existing records in the aggregate table and insert new records for anything that doesn't already exist for the primary account.
So my questions: does the existence of the If exists/elseif exists clauses actually make it so this trigger (and the rest of the triggers modeled on this one) does not actually handle multiple rows? If so, I don't think my problem would be solved by writing 2 or 3 separate triggers for each table as I still have to check for an existing record every time (i.e. an update/delete trigger and a separate insert trigger)? Should I move all of this to a stored procedure and pass in, for instance, a table variable that contains all the records from the inserted/deleted tables (something I thought of cruising around the forums)?
SQL is not my strong suit and triggers even less so. Any help from the more experienced would be immensely appreciated.
Short answer - no. The use of "if exists" does not prevent the correct handling of multi-row statements.
But let's be honest. If you struggle with tsql and triggers, then you should be writing separate triggers for each action UNTIL you have confidence in your approach and logic.
Your logic appears to be overly complicated, but no one knows your schema and how your tables are used. It also appears to be at least one error. In your insert section, you check for existence based on a.Status = 0. That same logic is not included in the associated insert statement. This has been propagated to the other 2 sets of logic.
For example, assume 5 rows inserted in SavedFiles. 1 matches a row in PlanLibraryMetrics, the others don't. What does your code do? After execution, only one row in PlanLibraryMetrics will be updated - you have skipped the logic needed to aggregate/insert the other 4 rows. Your deletion logic seems highly suspect with the right join; without knowing the actual and logic keys to the various tables it is difficult to understand.
And on that note - now is a good time to start commenting your code to help others (including yourself at a later date) understand what the code should be doing and perhaps why. And yes - please consider Damien's suggestion. A view, indexed or not, might be (probably is) a better approach - and certainly a safer, more easily maintained one.

SQL Server Cannot Update Table with Subqueries

I'm trying to update a temporary table called #deletedRecords which looks like this:
With the data from a table called log that looks like this:
The KeyValue in the log table is the same as the ID in #deletedRecords.
There is a column in #deletedRecords for every FieldName for any particular key value.
I tried to extract the values using the following query:
UPDATE #deletedRecords
SET PatientName = (SELECT ACL.OldValue WHERE ACL.FieldName = 'CptCode'),
ChargeNotes = (SELECT ACL.OldValue WHERE ACL.FieldName = 'ChargeNotes'),
Units = (SELECT ACL.OldValue WHERE ACL.FieldName = 'Units'),
ChargeStatusID = (SELECT ACL.OldValue WHERE ACL.FieldName = 'Units')
FROM Log ACL
JOIN #deletedRecords DR ON ACL.KeyValue = DR.ID
WHERE ACL.TableName = 'BillingCharge'
AND ACL.EventType = 'DELETE'
However when I run the query all of the columns to be updated in #deletedRecords are null. Can somebody please help explain what I'm missing?
Thanks in advance.
EDIT:
In response to #Yogesh Sharma's answer, I elected to use the CTE method. I would this that using the values from the CTE to join to additional tables and extract their values during the update.
e.g. The Log table doesn't contain an old value for the StatusName but it does contain the ChargeStatusID which could be used to join to another table that contains that information such as this table ChargeStatus:
Thus I modified #Yogesh Sharma's code to the following:
WITH cte AS
...
UPDATE d
SET d.PatientName = c.PatientName
, d.StatusName = cs.StatusName
FROM #deletedBillingChargeTemp d
JOIN cte c ON c.KeyValue = d.chargeID
JOIN ChargeStatus cs ON c.ChargeStatusID = cs.ChargeStatusID
However, once I add that secondary join, all of the updated values return to null as they were before #Yogesh Sharma's suggestions were implemented.
Your query does not work because the UPDATE is executed multiple times for each row in DR, considering only the conditions specified in the last three rows of your query (not the ones specified in the subqueries). The values that remain in the table are the ones that correspond to the ACL row used in the last execution (and the order of execution cannot be controlled). If for ACL row used in the last execution the subqueries return NULL, you will get a NULL result.
See the example in the https://learn.microsoft.com/en-us/sql/t-sql/queries/update-transact-sql topic, where it says "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.".
You should rewrite your query like this:
UPDATE #deletedRecords
SET PatientName = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'CptCode' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
ChargeNotes = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'ChargeNotes' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
Units = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'Units' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
ChargeStatusID = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'Units' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
)
FROM #deletedRecords DR
You would required to do some conditional aggregation for log table and do the JOINs in order to update the temporary table #deletedRecords records
So, the conditional approach could be achieve via CTE or Subquery
WITH cte AS
(
SELECT KeyValue,
MAX(CASE WHEN FieldName = 'CptCode' THEN OldValue END) PatientName,
MAX(CASE WHEN FieldName = 'ChargeNotes' THEN OldValue END) ChargeNotes,
...
FROM Log
WHERE TableName = 'BillingCharge' AND EventType = 'DELETE'
GROUP BY KeyValue
)
UPDATE d
SET d.PatientName = c.PatientName,
...
FROM #deletedRecords d
INNER JOIN cte c ON c.KeyValue = d.ID
The other way is to update your temporary table via correlation approach
UPDATE d
SET d.PatientName = (SELECT TOP 1 OldValue FROM Log WHERE KeyValue = d.ID AND
TableName = 'BillingCharge' AND EventType = 'DELETE' AND FieldName = 'CptCode'),
d.ChargeNotes= (SELECT TOP 1 OldValue FROM Log WHERE KeyValue = d.ID AND
TableName = 'BillingCharge' AND EventType = 'DELETE' AND FieldName = 'ChargeNotes'),
...
FROM #deletedRecords d
If your updated columns are NULL, these are it's possible causes:
Since you are doing a INNER JOIN, records might not be joining correctly by their joining column. Make sure both tables have the same values on the joining columns.
Since you are filtering in a WHERE clause, records might not fulfill your TableName and EventType filters. Make sure there are records that sucessfully INNER JOIN between them and they have the supplied TableName and EventType.
The values you are asigning are NULL. Make sure your subqueries return a not null value.
Table reference is off. When updating a table in SQL Server, always use the updating table alias if you are using one.
Use
UPDATE DR SET
YourColumn = Value
FROM
Log ACL
JOIN #deletedRecords DR ON -...
Instead of
UPDATE #deletedRecords SET
YourColumn = Value
FROM
Log ACL
JOIN #deletedRecords DR ON -...
Make sure you are NOT checking the variable table values on another batch, script or procedure. Variable tables scope are limited to current batch or procedure, while temporary tables remain as long as the session is alive.
Make sure that there isn't another statement that is setting those values as NULL after your update. Also keep an eye on your transactions (might not be commited or rolled back).

Issue in Update query

I have two tables called PassengerPaymentDetails and RoomInfo. Following is the query that I used to extract some values from existing PassengerPaymentDetails table.
SELECT
COUNT(*) AS Count, RequestReference, RoomTypeID, RoomCategory
FROM
[UL_SLHEV].[dbo].[PassengerPaymentDetails]
WHERE
Status != 0
GROUP BY
RoomTypeID, RoomCategory, RequestReference
As you can see I have RoomTypeID, RoomCategory and Count in the above mentioned table.
Following screenshot has the RoomInfo table:
I want to update the RoomInfo table data from the extracted Passengerpaymentdetails table. I can map these two tables with the RequestReference.
Need to update the count value in RoomInfo table according to the Passengerpaymentdetails table count value. Can anybody please help?
UPDATE:
Following is the code that I have tried so far. It is correctly return join table. I don't know how to set the value to the RoomInfo table with the getting table. And also here I am using left join for some purpose. I want to insert the value as well if the left table contains new row with the new roomtypeId. otherwise if the right table contains the same roomtypeID update the roomInfo with the updated value from passangerpaymentdetails table.
SELECT
t1.RequestReference as RoomInfoReq,
t1.Count as RoomInfoCount,
t1.RoomTypeID as RoomInfoID,
t1.RoomCategory as RoomInfoRoomCat,
l.RequestReference as PassangerReq,
l.Count as PassangerCount,
l.RoomTypeID as PassangerRoomTypeID,
l.RoomCategory as PassangerRoomCategory
FROM (
select
count(*) as Count,
RequestReference,
RoomTypeID,
RoomCategory
FROM
[UL_SLHEV].[dbo].[PassengerPaymentDetails]
where
Status!=0 group by RoomTypeID, RoomCategory, RequestReference)
as t1
Left JOIN RoomInfo as l on
t1.RequestReference = l.RequestReference and
t1.RoomTypeID = l.RoomTypeID and
t1.RoomCategory = l.RoomCategory and
l.Status!=0)
Something like that. It would be good if you provide DDL and DML instructions to test that, however you can see the logic how to do that:
UPDATE ri
SET [COUNT] = rd.[COUNT]
FROM RoomInfo ri
JOIN (SELECT
COUNT(*) AS [Count], RequestReference, RoomTypeID, RoomCategory
FROM
[UL_SLHEV].[dbo].[PassengerPaymentDetails]
WHERE
Status != 0
GROUP BY
RoomTypeID, RoomCategory, RequestReference) rd ON rd.RoomTypeID = ri.RoomTypeID
AND rd.RoomCategory = ri.RoomCategory
AND rd.RequestReference = ri.RequestReference

Resources