Get the Identity of Last Updated Row in SQL Server - sql-server

##IDENTITY returns the ID of the last row inserted, I want to retrieve the ID of the last row updated.
Here is my query:
UPDATE [Table]
SET Active = 1,
Subscribed = 1,
RenewDate = GETDATE(),
EndDate = DATEADD(mm,1,getdate()),
WHERE SC = #SC
AND Service = #Ser
How do I get the ID of this updated row?
The column is called TableID and I'm not using it in the query.

You cannot retrieve an ID since there is no ID being inserted.....
But you can:
just query the table using the same criteria as in your UPDATE:
SELECT TableID
FROM dbo.Table
WHERE SC = #SC AND Service = #Ser -- just use the same criteria
use the OUTPUT clause on the UPDATE to get that info:
UPDATE [Table]
SET Active = 1,
Subscribed = 1,
RenewDate = GETDATE(),
EndDate = DATEADD(mm,1,getdate())
OUTPUT Inserted.TableId -- output the TableID from the table
WHERE SC = #SC AND Service = #Ser
Read more about the OUTPUT clause on Technet - it can be used on INSERT and DELETE as well

you can try using this:
OUTPUT INSERTED.TableID
in your code it would look like this:
UPDATE [Table]
SET Active = 1,
Subscribed = 1,
RenewDate = GETDATE(),
EndDate = DATEADD(mm,1,getdate())
OUTPUT INSERTED.TableID
WHERE SC = #SC
AND Service = #Ser
Hope this helps.

I guess you need this one,
UPDATE [Table]
SET Active = 1,
Subscribed = 1,
RenewDate = GETDATE(),
EndDate = DATEADD(mm,1,getdate())
OUTPUT INSERTED.TABLE_PrimaryKeyID
WHERE SC = #SC
AND Service = #Ser
Main source: here

Try using
select ##identity gives last updated identity for the particular session
(or)
select scope_identity gives last updated identity for the particular scope
(or)
select ident_curr('tablename') give the last updated identity regardless of the session or scope but for that particular table.

Related

how to insert a value to both tables using join codeigniter 4 sql server

I'm trying to insert values to both tables at the same time. I'm using a form in my application where I use the inserted values from the form to inert them into the db. But now I'm inserting values to one table (Users).
public function registerUser($formdata){
helper('global');// a heper for randomString().
//Asign value to columns
$db_data['Emailaddress'] = $formdata['emailaddress'];
$db_data['Password'] = password_hash($formdata['password'], PASSWORD_DEFAULT);
$db_data['Status'] = 'Free';
$db_data['Token'] = randomString(32);
$db_data['FirstLogin'] = 0;
$db_data['Users.UsersKey'] = $db_data['UsersSettings.UsersKey'];
//insert to db
$this->db->table('Users', 'UsersSettings')->join('UsersSettings','Users.UsersKey = UsersSettings.UsersKey', 'inner')->insert($db_data);
}
public function updateUserSetting_proccess(){
$formdata = $this->request->getPostGet();
return $this->SettingsModel->update_user_settings($formdata);
}
The content of the Users table is:
SELECT TOP (1000) [UsersKey]
,[UniqueID]
,[Token]
,[ResetToken]
,[Emailaddress]
,[Password]
,[Status]
,[DateTimeAdded]
,[DateTimeLastUpdated]
,[FirstLogin]
FROM [dbo].[Users]
The UsersKey is inserted automaticly because of the auto increment.
The second table I want to use is UsersSettings with content:
SELECT TOP (1000) [UsersSettingsKey]
,[UsersKey]
,[FirstName]
,[LastName]
,[Logo]
,[Organization]
,[Address]
,[Number]
,[Addition]
,[Postcode]
,[City]
,[Country]
,[Language]
,[Theme]
,[CalcPercentage]
,[CalcAdminFee]
,[ColorPrimary]
,[ColorSecondary]
,[DateTimeLastUpdated]
FROM [dbo].[UsersSettings]
I want the UsersKey from UsersSettings have the same value in Users UsersKey.
I tried this:
join('UsersSettings','Users.UsersKey = UsersSettings.UsersKey', 'inner')
but it didn't help. Can someong give me some suggestions?
You'll need to perform the insert into table Users first in order to get the generated UsersKey.
Explanation of why inserting into table Users first is required, may be shown with the SQL equivalent:
declare #lv_UsersKey int
-- insert into table Users (only essential parts shown)
insert into Users(....) values (...)
-- capture UsersKey for inserted record
select #lv_UsersKey = cast(SCOPE_IDENTITY() as int)
-- then insert into UsersSettings (only essential parts shown)
insert into UsersSettings (UsersKey, ....) values (#lv_UsersKey, ...)
Transferring the above SQL to codeigniter will look like this:
$this->db->table('Users')->insert($db_data);
$inserted_users_key = $this->db->insert_id();
$db_data2['UsersKey'] = $inserted_users_key;
// some more init of $db_data2 here
$this->db->table('UsersSettings')->insert($db_data2);

SQL Trigger - DML statement Output Insert Error [duplicate]

I have a table that I want to add / update when a new row is added to a view but I am struggling to make this work.
My target table is Course Learner Progress and my view is Quiz_Results_For_Course_Learner_Progress.
I have created the view from a table that records quiz scores and is populated by a Zapier zap so I can't add a trigger to that table - which is why I have created the view of that table.
My trigger is as follows:
create trigger Update_Course_Progress_Quiz_Scores
on Quiz_Results_For_Course_Learner_Progress
instead of insert
as
declare #CompanyID int = (select CompanyID
from LEARNERS.dbo.ILR
where LEARNERID = LearnerID)
Merge Course_Learner_Progress as t
using inserted as s on t.CourseID = s.CourseID
and t.ModuleID = s.ModuleID
and t.LearnerID = s.LearnerID
and t.ContentID = s.ContentID
when not matched by Target then
insert (CompanyID, LearnerID, CourseID, ModuleID, ContentID, ContentType, Passmark, Score, [Status])
values (#CompanyID, s.LearnerID, s.CourseID, s.ModuleID,
s.ContentID, 4, s.Passmark, s.Quiz_Score, s.Status)
when matched then
update
set t.Score = s.Quiz_Score,
t.Status = s.[Status]
;
I can create the trigger successfully, but it doesn't insert / update a row in the Course_Learner_Progress table.
I would really welcome some help on this

SQL Server : assign sequential number not working

I'm trying to execute the following code in order add sequential number to a table.
declare #myvar2 int
set #myvar2 = 1
update _TEST_DATA
set ID = #myvar2, #myvar2 = #myvar2 + 1;
When I run this, I get the same ID assigned to multiple rows in my table. Any suggestions?
I'm on SQL Server 2012
your increment needs to be done in its own set statement, NOT within the "set" clause of the update statement.
Try this:
update _TEST_DATA set ID = #myvar2
-- update is done, now increment
set #myvar2 = #myvar2 + 1
You can use row number to generate a sequence which increments by 1:
DECLARE #myvar2 INT;
SET #myvar2 = 1;
UPDATE td
SET ID = rn
FROM _TEST_DATA td
INNER JOIN (SELECT ID,
#myvar2 + ROW_NUMBER() OVER (ORDER BY ID) rn
FROM _TEST_DATA
) a ON a.ID = td.ID;

MSSQL update multiple rows based on select statement

I am trying to update multiple rows in one table, based on a select statement on another table.
This is my query:
UPDATE dbo.[user_message_content]
SET [status] = 1
WHERE [message_id] = (SELECT [message_id] FROM dbo.[user_message] WHERE [receiver_id] = #userID)
AND [status] = 0
This select statement may return multiple rows, which leads me to this error:
Msg 512, Level 16, State 1, Procedure usp_profileUserMessageMarkAsRead, Line 11
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
What is the correct way to achieve what I need?
Thanks very much
If you want to update all those records, change the = to IN:
UPDATE dbo.[user_message_content]
SET [status] = 1
WHERE [message_id] IN
( SELECT [message_id] FROM dbo.[user_message] WHERE [receiver_id] = #userID )
AND [status] = 0
You can also use UPDATE with FROM clause http://msdn.microsoft.com/en-us/library/aa260662(SQL.80).aspx.
USE tempdb;
GO
create table #user_message_content([status] int, message_id int)
create table #user_message (message_id int,receiver_id int)
declare #UserID int
UPDATE mc
SET mc.[status] = 1
FROM #user_message_content mc join #user_message m on mc.message_id = m.message_id
WHERE m.receiver_id = #userID
AND mc.[status]=0;
drop table #user_message_content
drop table #user_message
I think you need to use a join to do this
USE dbo; // Sets the current database to dbo, I did this for readability
UPDATE user_message_content join user_message on user_message_content.message_id = user_message.message_id
SET user_message_content.status = 1
WHERE user_message.receiver_id = #userID;

SQL Update Table By Joining Same Table

I am working on an MS Access DB rewrite project that we are converting to a 2005 SQL server back-end/Winform front-end. I have a query in Access that I need to convert to run in SQL server. Here is the Access query:
UPDATE DISTINCTROW VAR, CancelsinTrans
INNER JOIN Trans ON (CancelsinTrans.ACCT = Trans.ACCT) AND (CancelsinTrans.ITEM_ID = Trans.ITEM_ID)
SET Trans.TRAN_CD = "1", Trans.LastUpdated = Date()
WHERE (((Trans.TRAN_CD)<>"1" Or (Trans.TRAN_CD) Is Null) AND
((CancelsinTrans.TRAN_DT)<[VAR]![Import1]) AND
((Trans.TRAN_DT)<[VAR]![Import1]));
The CancelsinTrans is a query that is pulling accounts from the Trans table - so basically it is joining on itself and performing an update.
Here is the CancelsInTrans query:
SELECT Trans.ACCT, Trans.TRAN_TYPE_CD, Trans.TRAN_SUBOR_CD, Trans.M_SRCE_CD, Trans.TRAN_RQST_CD, Trans.TRAN_AM, Trans.TRAN_DR_CR_CD, Trans.TRAN_CXL_CD, Trans.ACCTG_CD, Trans.ITEM_ID, Trans.TRAN_DT, Trans.TRAN_EXEC_TM, Trans.TRAN_QY, Trans.TRAN_NET, Trans.TRAN_EXEC_PR, Trans.M_SECURITY_NR, Trans.M_ORF_OR_ORDRNO, Trans.M_SEQ_NBR, Trans.TRAN_SETTL, Trans.M_ORDER_TAKER_ID, Trans.QUOTR_SEC, Trans.PROD_CD, Trans.SEC_CD, Trans.TRAN_EXEC_DT
FROM Trans
WHERE (((Trans.TRAN_TYPE_CD)="TR") AND ((Trans.TRAN_SUBOR_CD)="TR") AND ((Trans.TRAN_CD)="1") AND ((Trans.ACCTG_CD)="1"));
I am trying to figure out the best way to write this query. I was going to use a stored proc to run this update but should I use a table-function to get the set of records.
Any help would be great.
Thanks
The SQL Server equivalent would be something like the following:
Update Trans
Set TRAN_CD = '1'
, LastUpdated = GETDATE()
Where ( Trans.TRAN_CD <> '1' Or Trans.TRAN_CD Is Null )
And Trans.TRAN_DT < 'some var value'
And Exists (
Select 1
From CancelsinTrans As C1
Where C1.ACCT= Trans.ACCT
And C1.ITEM_ID = Trans.ITEM_ID
And C1.TRAN_DT < 'some var value'
)
In this case, through your parameterized query, you would replace some var value with the value from [VAR]![Import1] which I presume was a form value.
UPDATE
Given that the CancelsInTran query encapsulates the Trans table, you can eliminate the join like so:
Update Trans
Set TRAN_CD = '1'
, LastUpdated = GetDate()
Where TRAN_TYPE_CD = 'TR'
And TRAN_SUBOR_CD = 'TR'
And ACCTG_CD = '1'
And ( TRAN_CD <> '1' Or TRAN_CD Is Null )
And TRAN_DT < 'some value'

Resources