stored procedure with insert & update using identity column - sql

I have a table called 'tasks' in that 'task id' is identity column, for that table I have to write save stored procedure, in which when 'task id' is not given it should insert the values and when 'task id' is given it should update the table.
how can this achievable when task id is identity column could anyone explain with example.
here is the code
Alter PROCEDURE TaskSave
(
#taskid int,
#ProjectId int,
#EmployeeId int,
#TaskName nvarchar(50),
#Duration_Hrs int,
#StartDate nvarchar(20),
#FinishDate nvarchar(20),
#CreateUserId int,
#CreatedDate nvarchar(20),
#ModifiedUserID int,
#ModifiedDate nvarchar(20),
#Is_CommonTask bit
) AS
BEGIN
IF Exists( select null from TblTasks where TaskId=#TaskId)
BEGIN
INSERT TblTasks
VALUES (#ProjectId,#EmployeeId,#TaskName,#Duration_Hrs,
#StartDate,#FinishDate,#CreateUserId,#CreatedDate,
#ModifiedUserID,#ModifiedDate,#Is_CommonTask)
END
ELSE
BEGIN
UPDATE TblTasks SET
StartDate=#StartDate,FinishDate=#FinishDate,
Duration_Hrs=#Duration_Hrs
WHERE TaskId=#TaskId
END
END
GO

First of all, give your input variable TaskID a default value like below, then simply check to see if the variable is NULL, if so, insert a new row
Alter PROCEDURE TaskSave
(
#taskid int = NULL,
#ProjectId int,
#EmployeeId int,
#TaskName nvarchar(50),
#Duration_Hrs int,
#StartDate nvarchar(20),
#FinishDate nvarchar(20),
#CreateUserId int,
#CreatedDate nvarchar(20),
#ModifiedUserID int,
#ModifiedDate nvarchar(20),
#Is_CommonTask bit
) AS
BEGIN
IF #taskid IS NULL
BEGIN
INSERT TblTasks
VALUES (#ProjectId,#EmployeeId,#TaskName,#Duration_Hrs,
#StartDate,#FinishDate,#CreateUserId,#CreatedDate,
#ModifiedUserID,#ModifiedDate,#Is_CommonTask)
END
ELSE
BEGIN
UPDATE TblTasks SET
StartDate=#StartDate,FinishDate=#FinishDate,
Duration_Hrs=#Duration_Hrs
WHERE TaskId=#TaskId
END
END
GO

You are close, check if the record doesn't exist and perform insert, otherwise update. You can also declare the #TaskId parameter as OUTPUT and return it when inserting, using the SCOPE_IDENTITY() function:
ALTER PROCEDURE TaskSave(
#TaskId INT = NULL OUTPUT
, #ProjectId INT
, #EmployeeId INT
, #TaskName NVARCHAR(50)
, #Duration_Hrs INT
, #StartDate NVARCHAR(20)
, #FinishDate NVARCHAR(20)
, #CreateUserId INT
, #CreatedDate NVARCHAR(20)
, #ModifiedUserID INT
, #ModifiedDate NVARCHAR(20)
, #Is_CommonTask BIT
)
AS
BEGIN
IF NOT(EXISTS(SELECT * FROM TblTasks WHERE TaskId = #TaskId))
BEGIN
INSERT INTO TblTasks(
ProjectId
, EmployeeId
, TaskName
, Duration_Hrs
, StartDate
, FinishDate
, CreateUserId
, CreatedDate
, ModifiedUserID
, ModifiedDate
, Is_CommonTask
)
VALUES(
#ProjectId
, #EmployeeId
, #TaskName
, #Duration_Hrs
, #StartDate
, #FinishDate
, #CreateUserId
, #CreatedDate
, #ModifiedUserID
, #ModifiedDate
, #Is_CommonTask
)
SET #TaskId = SCOPE_IDENTITY()
END
ELSE
BEGIN
UPDATE TblTasks SET
StartDate = #StartDate
, FinishDate = #FinishDate
, Duration_Hrs = #Duration_Hrs
WHERE TaskId=#TaskId
END
END
GO

declare #taskid parameter as NULL. the if it is null then insert else update. see below.
Alter PROCEDURE TaskSave
(
#taskid int =NULL,
#ProjectId int,
#EmployeeId int,
#TaskName nvarchar(50),
#Duration_Hrs int,
#StartDate nvarchar(20),
#FinishDate nvarchar(20),
#CreateUserId int,
#CreatedDate nvarchar(20),
#ModifiedUserID int,
#ModifiedDate nvarchar(20),
#Is_CommonTask bit
) AS
BEGIN
if #taskid is null
BEGIN
INSERT TblTasks
VALUES (#ProjectId,#EmployeeId,#TaskName,#Duration_Hrs,
#StartDate,#FinishDate,#CreateUserId,#CreatedDate,
#ModifiedUserID,#ModifiedDate,#Is_CommonTask)
END
ELSE
BEGIN
UPDATE TblTasks SET
StartDate=#StartDate,FinishDate=#FinishDate,
Duration_Hrs=#Duration_Hrs
WHERE TaskId=#taskid
END
END
GO

In cases like these, I used to create a general stored procedure which is capable of inserting, updating and deleting an item. The general pattern looked like this
create procedure Modify_MyTable
#Action char(1),
#Data int,
#PK int output
as
if #Action = 'I' begin -- Insert
insert into MyTable (Data) values (#Data)
set #PK = Scope_Identity()
end
if #Action = 'M' begin -- Modify
update MyTable set Data = #Data where PKID = #PK
end
if #Action = 'D' begin -- Delete
delete MyTable where PKID = #PK
end
It is quite a while ago when I used this but I found it quite handy as I have all the manipulation code in one SP (I could have used three, of course) and could also add logging features and other basic logic in this procedure.
I am not saying that this is still the best method but it should show the basic logic.

Related

SQL Server : Dynamic Query in Stored Procedure in

I tried to write dynamic query in SQL Server. However I get warning like below,
The Selected stored procedure or function returns no columns
I have been trying to achieve this however it still does not run.
Where did I miss ?
ALTER PROCEDURE [dbo].[S_ProjeGetir1]
#ID int=0,
#AktifMi int,
#ProjeFirma int,
#Icinde int,
#AramaText Varchar(500),
#Arasinda1 Varchar(50),
#Arasinda2 Varchar(50)
AS
BEGIN
Create Table #TempTable
(Sonuc int
,ID int
,FirmaID int
,PrismProjeID int
,ProjeAdi nvarchar(150)
,RgID uniqueidentifier
,HaritaEnlem nvarchar(25)
,HaritaBoylam nvarchar(25)
,ProjeTeslimTarihi datetime
,HemenTeslimMi bit
,Adres nvarchar(250)
,AdresUlkeID int
,AdresILID int
,AdresILceID int
,AdresSemtID int
,KonutSayisi int
,LansmanTarihi datetime
,OfisSayisi int
,MagazaSayisi int
,BlokSayisi int
,YesilAlan int
,KrediyeUygunMu bit
,AktifMi bit
,UcBoyutVarMi bit
,UlkeAdi nvarchar(150)
,Sehir nvarchar(50)
,Ilce nvarchar(50)
,Semt nvarchar(50)
,FirmaAdi nvarchar(100)
,StokSonGuncellemeTarihi datetime)
Declare #SqlText varchar(8000),
#AktifPasif bit
Set #AktifPasif=Case When #AktifMi=0 Then 1 When #AktifMi=1 Then 0 End
SET NOCOUNT ON
BEGIN TRY
Set #SqlText=' SELECT 1 Sonuc ,[ID],[FirmaID] ,[PrismProjeID],[ProjeAdi] ,[RgID] ,[HaritaEnlem] ,[HaritaBoylam] ,[ProjeTeslimTarihi]
,[HemenTeslimMi],[Adres] ,[AdresUlkeID] ,[AdresILID] ,[AdresILceID] ,[AdresSemtID] ,[KonutSayisi]
,[LansmanTarihi],[OfisSayisi] ,[MagazaSayisi],[BlokSayisi],[YesilAlan] ,[KrediyeUygunMu],[AktifMi]
,[UcBoyutVarMi] ,[UlkeAdi] ,[Sehir] ,[Ilce] ,[Semt]
,[FirmaAdi] ,[StokSonGuncellemeTarihi]
FROM [dbo].[V_Proje] AS P WITH (NOLOCK)
WHERE 1=1 '
If #ID>0 Set --ID ye Göre İlgili Kayıdı almak için
#SqlText=#SqlText +' and ID=' +cast(#ID as Varchar(50))
Else
Begin
--Aktif ise veya Pasif ise
if #AktifMi=0 or #AktifMi=1
Begin
Set #SqlText=#SqlText +' and AktifMi='+cast(#AktifPasif as varchar(50))
End
--Bütün Alanları sorgulamak için
Set #SqlText=#SqlText +' and CASE WHEN '+cast(#ProjeFirma as varchar(50))+'=1 THEN Upper(ProjeAdi)
WHEN '+cast(#ProjeFirma as varchar(50))+'=0 THEN Upper(FirmaAdi)
WHEN '+cast(#ProjeFirma as varchar(50))+'=2 THEN Upper(HaritaEnlem)
WHEN '+cast(#ProjeFirma as varchar(50))+'=3 THEN Upper(HaritaBoylam)
WHEN '+cast(#ProjeFirma as varchar(50))+'=4 THEN Upper(Adres)'
If #Icinde=0--İçinde
Set #SqlText=#SqlText +' END Like ''%'+#AramaText+'%'' '
If #Icinde=1--İle Başlayan
Set #SqlText=#SqlText +' END Like '''+#AramaText+'%'' '
If #Icinde=2--Arasında
Set #SqlText=#SqlText +' END between '''+ #Arasinda1+''' and '''+#Arasinda2+''''
--select #SQLTEXT
End
exec('insert into #TempTable ' + #SqlText)
Select Sonuc, [ID],[FirmaID],[PrismProjeID],[ProjeAdi] ,[RgID] ,[HaritaEnlem],[HaritaBoylam],[ProjeTeslimTarihi],[HemenTeslimMi]
,[Adres] ,[AdresUlkeID] ,[AdresILID],[AdresILceID] ,[AdresSemtID],[KonutSayisi] ,[LansmanTarihi] ,[OfisSayisi]
,[MagazaSayisi],[BlokSayisi] ,[YesilAlan],[KrediyeUygunMu],[AktifMi] ,[UcBoyutVarMi],[UlkeAdi],[Sehir] ,[Ilce],[Semt]
,[FirmaAdi] ,[StokSonGuncellemeTarihi]
From #TempTable AS T WITH (NOLOCK)
END TRY
BEGIN CATCH
SELECT -1 AS Sonuc -- EXCEPTION
END CATCH
SET NOCOUNT OFF
END
Any help will be appreciated.
Thanks
I am not sure if what i am going to tell is going to work for EF, but i had a similar case in LINQ to SQL classes.
Backup the code of your Stored Procedure
Create a single SELECT statement with appropriate values, in your Stored Procedure like the following:
ALTER PROCEDURE [dbo].[S_ProjeGetir1]
#ID int=0,
#AktifMi int,
#ProjeFirma int,
#Icinde int,
#AramaText Varchar(500),
#Arasinda1 Varchar(50),
#Arasinda2 Varchar(50)
AS
BEGIN
Select CONVERT(VARCHAR(30),'') AS Sonuc, -- Make sure to convert to what your
0 AS [ID],
0 AS [FirmaID],
0 AS [PrismProjeID],
...
END
Import this Stored Procedure in EF
If all goes well, restore the backed up code in the Stored Procedure.

execute stored procedure based on condition

i tried to insert data in database using stored procedure but according to some condition. for example if data is already exists in database the the stored procedure should not be executed.
i am doing the following code but it return 0 every time rather then i want. What can i do
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
declare #result int
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
set #result=4;
return #result;
end
else
begin
insert into Registration values(#cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass );
set #result =0;
return #result;
end
You can simply proceed as follows;
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
BEGIN
DECLARE #return int
if NOT EXISTS(select Email_ID from Registration where Email_ID=#email)
insert into Registration values(#cid, #firstname, #lastname,
#dob, #gender, #add, #email,
#quali, #yop, #exp, #pass )
If (##ERROR <> 0)
Begin
Set #return = 4
Else
Set #return = 0
End
Return #return
END
You can use raiseerror event for this scenario
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
RAISERROR(N'Email id already exist.', 10, 2,'')
end
Here 10 is severity level and according to severity level sql server identified as info meassage or exception. For more information
RaiseError
Database Engine Severity Levels
Try this one -
ALTER PROCEDURE dbo.SaveUser
(
#cid INT,
#firstname VARCHAR(20),
#lastname VARCHAR(20),
#dob DATETIME,
#gender VARCHAR(20),
#add VARCHAR(100),
#email VARCHAR(40),
#quali VARCHAR(20),
#yop VARCHAR(15),
#exp VARCHAR(10),
#pass VARCHAR(20)
)
AS BEGIN
IF NOT EXISTS(
SELECT 1
FROM dbo.Registration
WHERE Email_ID = #email
) BEGIN
INSERT INTO dbo.Registration
SELECT #cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass
RETURN 0;
END
RETURN 4;
END

SQL call a SP from another SP

Can I please have some help with the syntax of a SP in SQL.
Here is my code:
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
Set #v_Value = usp_GetValue(#ID, #Description)
END
In the usp_InsertValue SP, I am wanting to declare and set a variable. Once the variable has been declared, I then wish to call another SP with parameters to set the value of the declared variable.
I am not sure of the syntax. May I please have some help?
UPDATE
I have updated my above code using your function. How do I Set the #v_Value from the usp_GetValue function.
I am getting this error:
'usp_GetValue' is not a recognized built-in function name.
UPDATE2
Here is my full code:
CREATE PROCEDURE usp_PersonCategoryLookupTesting
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertPersonTesting
(
#IDTest VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#AddressLine1 VARCHAR(50),
#AddressLine2 VARCHAR(50),
#AddressLine3 VARCHAR(50),
#MobilePhone VARCHAR(20),
#HomePhone VARCHAR(20),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #PersonCategory VARCHAR(15)
EXEC usp_PersonCategoryLookupTest #ID, #Description, #PersonCategory
INSERT INTO Person(FirstName, LastName, AddressLine1, AddressLine2, AddressLine3, MobilePhone, HomePhone, DateModified, PersonCategory, Comment)
VALUES (#FirstName, #LastName, #AddressLine1, #AddressLine2, #AddressLine3, #MobilePhone, #HomePhone, GETDATE (), #PersonCategory, #Comment)
END
I am getting this error in my application that is calling the SQL code:
Conversion failed when converting the varchar value '123Client' to data type int.
I am using the values "123" and "Client" for #IDTest and #Description.
I think output parameters should be the proper way:
See this post:
stored procedure returns varchar
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
EXEC usp_GetValue #ID, #Description, #v_Value
-- use #v_Value here...
END
You can only use a function like that, not stored procedure. Stored Procedures only return integer values.
For SP, you need to create out parameters to retrieve the values. For this scenario, it is better to create a function
CREATE FUNCTION usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
)
RETURNS VARCHAR(50)
AS
BEGIN
return #ID + #Description
END
Then call it:
SET #v_value = dbo.usp_GetValue('John','Doe') --output: John Doe
If you insist you want a SP, which is not proper for this, there are 2 ways
1) An out parameter
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#Result varchar(20) OUTPUT
)
AS
BEGIN
SET #Result = #ID + #Description
END
Then call it:
Declare #v_Value VARCHAR(15)
Set #v_Value = EXEC usp_GetValue #ID, #Description, #v_Value OUTPUT
2) Select from it
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
SELECT #ID + #Description
END
Use it like this:
declare #tempresult as table(v_value as varchar(15))
INSERT INTO #tempresult
EXEC usp_GetValue #ID, #Description
Select Top 1 #v_value = v_value From #tempresult
My advise is use the function approach.

insert stored procedure, check if row exists

I am using sql server 2005 and want to insert a row into a database table, however i am getting an incorrect syntax at values. and also i want to make sure what i am adding already doesnt exist i think this is right but i have that one syntax error.
create PROCEDURE [dbo].[directway]
#tour as varchar(50),
#tourname as varchar(50),
#taskname as varchar(50) ,
#deptdate as varchar(50),
#tasktype as varchar(50) ,
#desc as varchar(50) ,
#duedate as varchar(50) ,
#agent as varchar(50),
#graceperiod as varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO dashboardtasks
([tour]
,[tourname]
,[taskname]
,[deptdate]
,[tasktype]
,[desc]
,[duedate]
,[agent]
,[graceperiod]
VALUES (#tour,
#tourname,
#taskname ,
#deptdate,
#tasktype ,
#desc ,
#duedate ,
#agent ,
#graceperiod
)
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE ( #tour = dashboardtasks.tour
and #taskname = dashboardtasks.taskname
and #deptdate = dashboardtasks.deptdate
and #duedate = dashboardtasks.duedate
and #tourname = dashboardtasks.tourname
and #agent = dashboardtasks.agent
)
)
END
You've just got it a bit the wrong way round
IF NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE ( #tour = dashboardtasks.tour
and #taskname = dashboardtasks.taskname
and #deptdate = dashboardtasks.deptdate
and #duedate = dashboardtasks.duedate
and #tourname = dashboardtasks.tourname
and #agent = dashboardtasks.agent
)
)
BEGIN
INSERT INTO dashboardtasks
([tour]
,[tourname]
,[taskname]
,[deptdate]
,[tasktype]
,[desc]
,[duedate]
,[agent]
,[graceperiod])
VALUES (#tour,
#tourname,
#taskname ,
#deptdate,
#tasktype ,
#desc ,
#duedate ,
#agent ,
#graceperiod
)
END

SQL Server: Return uniqueidentifier from stored procedure

Can I return UNIQUEIDENTIFIER from a stored procedure using the RETURN statement or is it only by using the OUTPUT statement?
i.e to return the PersonID UNIQUEIDENTIFIER:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT
AS
DECLARE #Count INT
DECLARE #JobFileGUID UNIQUEIDENTIFIER
-- Check if job exists?
SET #Count = (SELECT COUNT(Name) AS Name FROM Person WHERE Name=#Name)
IF #Count < 1
BEGIN
SET #PersonGUID = NEWID();
INSERT INTO Person
(PersonID, Name, [Desc])
VALUES (#PersonGUID, #Name, #Desc)
END
SELECT #PersonGUID = Person.PersonID
FROM Person
WHERE Name = #Name
RETURN #PersonGUID
GO
Thanks
In stored procedure - only using the OUTPUT statement. In function - return.
Use:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT,
#PersonGUID UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #PersonGUID = ...
END
How to call:
DECLARE
#name NVARCHAR(255),
#desc TEXT,
#personGUID UNIQUEIDENTIFIER
SET #name = 'Bob'
SET #desc = 'One handsome man.'
EXEC [Database].[schema].CreatePerson #name, #desc, #personGUID OUTPUT
From the documentation you can actually see that a return in a stored procedure is actually used as a response code, hence you get the exception when trying to return a uniqueidentifier.
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-ver16#return-data-using-a-return-code
How I solved it, is by just performing a SELECT after the insert of the generated unique identifier.
DECLARE #ReportId UNIQUEIDENTIFIER;
SET #ReportId = NEWID();
INSERT INTO [dbo].[Report]
([ReportId]
,[ReportName])
VALUES
(#ReportId
,#ReportName)
SELECT #ReportId as ReportIdInternal
You'll have to see how to perform that with multiple selects though.
CREATE TABLE [dbo].[tbl_Clients]( [ClientID] [uniqueidentifier] NULL, [ClientName] varchar NULL, [ClientEnabled] [bit] NULL ) ON [PRIMARY]
GO
CREATE PROCEDURE [dbo].[sp_ClientCreate] #in_ClientName varchar(250) = "New Client 123", #in_ClientEnabled bit, #out_ClientId uniqueidentifier OUTPUT AS
SET #out_ClientId = NEWID();
INSERT INTO tbl_Clients(ClientId, ClientName, ClientEnabled) VALUES( #out_ClientId, #in_ClientName, #in_ClientEnabled)
DECLARE #return_value int, #out_ClientId uniqueidentifier
EXEC #return_value = [dbo].[sp_ClientCreate] #in_ClientName = N'111', #in_ClientEnabled = 1, #out_ClientId = #out_ClientId OUTPUT
SELECT #out_ClientId as N'#out_ClientId'
SELECT 'Return Value' = #return_value
GO
Result:-59A6D7FE-8C9A-4ED3-8FC6-31A989CCC8DB