Update and Insert Stored Procedure - sql

I want to create a stored procedure that performs insert or update operation on a column if
that column does not contains a value that already exists in database it should allow insert when COUNT(field) = 0 or update when COUNT(field)=0 or 1 And I should know that either of these operation is performed or not.
Please solve my problem using COUNT not Exists because that won't work for UPDATE.
I am working in ASP.net - I have two columns of a table that are needed to be kept unique without using the unique constraint. So I want a procedure like this:
create proc usp_checkall #field1 varchar(20),
#field2 varchar(20),
#ID int,
#count int output
Now your query on updating/inserting #field1 & #field2 on basis of #id

If you happen to have SQL Server 2008, you could also try:
MERGE dbo.SomeTable AS target
USING (SELECT #ID, #Field_1, #Field_2) AS source (ID, Field_1, Field_2)
ON (target.ID = source.ID)
WHEN MATCHED THEN
UPDATE SET Field_1 = source.Field_1, Field_2 = source.Field_2
WHEN NOT MATCHED THEN
INSERT (ID, Field_1, Field_2)
VALUES (source.ID, source.Field_1, source.Field_2)

Use:
INSERT INTO your_table
(column)
VALUES
([ your_value ])
WHERE NOT EXISTS (SELECT NULL
FROM your_table
WHERE t.column = [ your_value ])
That will work on SQL Server, MySQL, Oracle, Postgres. All that's needed is to use the db appropriate variable reference. IE: For MySQL & SQL Server:
INSERT INTO your_table
(column)
VALUES
( #your_value )
WHERE NOT EXISTS (SELECT NULL
FROM your_table
WHERE t.column = #your_value)
To see if anything was inserted, get the value based on ##ROWCOUNT if using SQL Server. Use SQL%ROWCOUNT if you are using Oracle.

if Exists select * from Yourtable WHere Your Criteria
begin
update ...
end
else
begin
insert ...
end

This kind of approach will do the trick. #AlreadyExisted could be an OUTPUT parameter on the sproc for your calling code to check once it's returned.
DECLARE #AlreadyExisted BIT
SET #AlreadyExisted = 0
IF EXISTS(SELECT * FROM YourTable WHERE YourField = #FieldValue)
BEGIN
-- Record already exists
SET #AlreadyExisted = 1
UPDATE YourTable
SET....
WHERE YourField = #FieldValue
END
ELSE
BEGIN
-- Record does not already exist
INSERT YourTable (YourField,....) VALUES (#FieldValue,.....)
END

Related

Automation Anywhere SQL results

I am trying to capture if my SQL Query have 0 rows or multiple rows. If it has 0 rows then I will insert, if 1 will perform an update, if > 1 will perform additional analysis.
Is there a way I can see if my query resulted in x results or no results in automation anywhere?
Any assistance will be appreciated.
You can make use of if exists and if not exists and check if rows exists or not, or even if there are multiple before doing the insert.
Here is a simple example using if not exists where if the row doesn't exist on dbo.Table it will insert a row. If it already exists then the ID will be logged to an Error table.
declare #InsertID int = 5, #Name nvarchar(max) = 'some name'
if ((select count(1) from dbo.Table where ID = #InsertID) > 1) -- detect error; more than one record for an id
begin
insert into dbo.Error (ErrorID, ErrorDate)
select #InsertID, getdate()
end
else if not exists (select 1 from dbo.Table where ID = #InsertID) -- no record exists for ID, insert it
begin
insert into dbo.Table (ID, Name)
select #InsertID, #Name
else if exists (select 1 from dbo.Table where ID = #InsertID) -- update the single record
begin
update dbo.Table set Name = #Name where ID = #InsertID
end
A2019 returns the results of a SQL Query as a table...
You could have an if statement right after your query which checks to see if the row count of the returned table is > 0 then take action accordingly.

IF ELSE workaround in Sqlite

I am trying to do a simple upsert query in SQL. This query works in SQL Server
IF (EXISTS (SELECT * FROM TableName WHERE SomeId = #SomeId AND SomeOtherId = #SomeOtherId))
BEGIN
UPDATE TableName
SET "SomeColumn" = #SomeValue
WHERE SomeId = #SomeId AND SomeOtherId = #SomeOtherId;
END
ELSE
BEGIN
INSERT INTO TableName VALUES (#SomeId, #SomeOtherId, #SomeValue);
END
However, our Unit tests run on Sqlite and in general we want to write vanilla SQL, so this IF ELSE won't work.
I was trying to pull it off with CASE WHEN but I can't get it right. Can somebody post a working Sqlite query?
Thanks in advance,
Marko
If there is (or you can create) a unique constraint for the combination of the columns SomeId and SomeOtherId, then you might use UPSERT like this:
INSERT INTO TableName(SomeId, SomeOtherId, SomeColumn)
VALUES(#SomeId, #SomeOtherId, #SomeValue)
ON CONFLICT(SomeId, SomeOtherId) DO
UPDATE SET SomeColumn = #SomeValue;
If not then use 2 statements:
UPDATE TableName
SET SomeColumn = #SomeValue
WHERE SomeId = #SomeId AND SomeOtherId = #SomeOtherId;
INSERT INTO TableName (SomeId, SomeOtherId, SomeColumn)
SELECT #SomeId, #SomeOtherId, #SomeValue
WHERE NOT EXISTS (
SELECT 1 FROM TableName
WHERE SomeId = #SomeId AND SomeOtherId = #SomeOtherId
);
The UPDATE statement will succeed only if there is a row under the conditions you specify, otherwise it will do nothing.
The INSERT statement will succeed only if there is not a row under the conditions you specify, otherwise it will do nothing.

MS SQL Server Trigger if else insert

I'm trying to write a trigger but I need help. How can I write this type of trigger?
If data coming null insert into this parameter?
There is my codes
CREATE TRIGGER AddDayOn ON Control
INSTEAD OF INSERT
AS
DECLARE #first DATETIME,#second DATETIME,#name NVARCHAR(11),#birth DATETIME
SELECT #first = First,
#second = Second,
#name = Name,
#birth = Birth
FROM inserted
INSERT INTO Control(
Name,
First,
Birth,
Second,
Prob
)
VALUES
( #name,
#first,
#birth,
DATEADD(DAY,220,#first),
DATEADD(DAY 250,#first))
I need to chance this trigger with if-else.Because i have 3 more parameters(Four,Five,Six). I'm try to write something like that
If #first not null DATEADD..
If #four not null DATEADD.. like that
you can use exists in your statement like this:
insert into table1(col1,col2)
select col1,col2 from inserted as i
where not exists(select 0 from table1 where relatedkey=i.relatedkey)

Update Trigger For Multiple Rows

I am trying to Insert data in a table named "Candidate_Post_Info_Table_ChangeLogs" whenever a record is updated in another table named "Candidate_Personal_Info_Table". my code works fine whenever a single record is updated but when i try to updated multiple rows it gives error:
"Sub query returned more then 1 value".
Following is my code :
ALTER TRIGGER [dbo].[Candidate_PostInfo_UPDATE]
ON [dbo].[Candidate_Post_Info_Table]
AFTER UPDATE
AS
BEGIN
IF ##ROWCOUNT = 0
RETURN
DECLARE #Candidate_Post_ID int
DECLARE #Candidate_ID varchar(50)
DECLARE #Action VARCHAR(50)
DECLARE #OldValue VARCHAR(MAX)
DECLARE #NewValue VARCHAR(MAX)
DECLARE #Admin_id int
IF UPDATE(Verified)
BEGIN
SET #Action = 'Changed Verification Status'
SET #Candidate_Post_ID = (Select ID From inserted)
SET #Candidate_ID = (Select Identity_Number from inserted)
SET #NewValue = (Select Verified From inserted)
SET #OldValue = (Select Verified From deleted)
IF(#NewValue != #OldValue)
BEGIN
INSERT INTO Candidate_Post_Info_Table_ChangeLogs(Candidate_Post_ID, Candidate_ID, Change_DateTime, action, NewValue, OldValue, Admin_ID)
VALUES(#Candidate_Post_ID, #Candidate_ID, GETDATE(), #Action, #NewValue, #OldValue, '1')
END
END
END
i have searched stack overflow for this issue but couldn't get any related answer specific to this scenario.
When you insert/update multiple rows into a table, the Inserted temporary table used by the system holds all of the values from all of the rows that were inserted or updated.
Therefore, if you do an update to 6 rows, the Inserted table will also have 6 rows, and doing something like this:
SET #Candidate_Post_ID = (Select ID From inserted)
Will return an error, just the same as doing this:
SET #Candidate_Post_ID = (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6)
From the looks of things, you tried to do this with an iterative approach. Set-based is better. Maybe consider doing it like this in the body of your TRIGGER (without all of the parameters...):
IF UPDATE(Verified)
BEGIN
INSERT INTO Candidate_Post_Info_Table_ChangeLogs
(
Candidate_Post_ID
,Candidate_ID
,Change_DateTime
,action
,NewValue
,OldValue
,Admin_ID
)
SELECT
I.ID
,I.Identity_Number
,GETDATE()
,'Changed Verification Status'
,I.Verified
,O.Verified
,'1'
FROM Inserted I
INNER JOIN Deleted O
ON I.ID = O.ID -- Check this condition to make sure it's a unique join per row
WHERE I.Verified <> O.Verified
END
A similar case was solved in the following thread using cursors.... please check it
SQL Server A trigger to work on multiple row inserts
Also the below thread gives the solution based on set based approach
SQL Server - Rewrite trigger to avoid cursor based approach
*Both the above threads are from stack overflow...

What's the best way to lock a record while it is being updated?

If I need to SELECT a value from a table column (happens to be the primary key column) based on a relatively complex WHERE clause in the stored procedure, and I then want to update that record without any other concurrent stored procedures SELECTing the same record, is it as simple as just using a transaction? Or do I also need to up the isolation to Repeatable Read?
It looks like this:
Alter Procedure Blah
As
Declare #targetval int
update table1 set field9 = 1, #targetval = field1 where field1 = (
SELECT TOP 1 field1
FROM table1 t
WHERE
(t.field2 = 'this') AND (t.field3 = 'that') AND (t.field4 = 'yep') AND (t.field9 <> 1))
return
I then get my targetval in my program so that I can do work on it, and meanwhile I don't have to worry about other worker threads grabbing the same targetval.
I'm talking SQL 2000, SQL 2005, and SQL 2008 here.
Adding ROWLOCK,UPDLOCK to the sub query should do it.
ALTER PROCEDURE Blah
AS
DECLARE #targetval INT
UPDATE table1
SET field9 = 1,
#targetval = field1
WHERE field1 = (SELECT TOP 1 field1
FROM table1 t WITH (rowlock, updlock)
WHERE ( t.field2 = 'this' )
AND ( t.field3 = 'that' )
AND ( t.field4 = 'yep' )
AND ( t.field9 <> 1 ))
RETURN
Updated
The currently accepted answer to this question does not use updlock. I'm not at all convinced that this will work. As far as I can see from testing in this type of query with a sub query SQL Server will only take S locks for the sub query. Sometimes however the sub query will get optimised out so this approach might appear to work as in Query 2.
Test Script - Setup
CREATE TABLE test_table
(
id int identity(1,1) primary key,
col char(40)
)
INSERT INTO test_table
SELECT NEWID() FROM sys.objects
Query 1
update test_table
set col=NEWID()
where id=(SELECT top (1) id from test_table )
Query 2
update test_table
set col=NEWID()
where id=(SELECT max(id) from test_table)