insert stored procedure, check if row exists - sql-server-2005

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

Related

if statement in transact sql

I have a stored procedure that I need to enhance. This is what I have now.
ALTER PROCEDURE [rw].[sp_EFT_NoticeXLS2]
(#Scope varchar(50)
, #AcctPeriod char(6)
, #CompanyID nchar(10))
AS ......
What I need to do is to pass a variable #GLsubacct to it only if #CompanyID is 0000.
I tried.....
ALTER PROCEDURE [rw].[sp_EFT_NoticeXLS2]
(#Scope varchar(50)
, #AcctPeriod char(6)
, #CompanyID nchar(10)
IF (#CompanyID IS 0000)
#GLsubacct varchar(1000))
AS ....
but I am getting an error. I am not sure how to write the if statement. I need all the help I can get, thanks!
You can't do that.
You can setup the second variable to be "nullable"...making it "optional".
Then you can raise an exception if the rules don't follow.
Generic example:
Use Northwind
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[uspDoSomething]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[uspDoSomething]
GO
CREATE PROCEDURE [dbo].[uspDoSomething]
(
#CustomerId varchar(12)
, #PostalCode varchar(12) = NULL
)
AS
SET NOCOUNT ON;
if #CustomerId = 'ALFKI' AND #PostalCode IS NULL
BEGIN
THROW 51000, 'You must supply a Postal Code with this #CustomerId.', 1;
END
select * from dbo.Customers c
where
c.CustomerID = #CustomerId
AND
( #PostalCode IS NULL OR c.PostalCode = #PostalCode )
GO
/* examples */
exec [dbo].[uspDoSomething] 'ALFKI' , '12209'
exec [dbo].[uspDoSomething] 'ALFKI'
exec [dbo].[uspDoSomething] 'ANATR' , '05021'
You may not need to use the IF statement below depending on what your Stored Procedure actually does, however what you're looking for is probably something like this:
ALTER PROCEDURE [rw].[sp_EFT_NoticeXLS2]
#Scope varchar(50),
#AcctPeriod char(6),
#CompanyID nchar(10),
#GLsubacct varchar(1000) = NULL
AS
BEGIN
IF #CompanyID = '0000'
BEGIN
-- CompanyID is 0000
END
ELSE
BEGIN
-- CompanyID is NOT 0000
END
END
GO

execute stored procedure with a loop and combine results

I have a stored procedure in SQL server 2008.
This stored procedure (lets call it sp1), accepts ID (string),FromDate,ToDate and returns col1,col2,col3
I tried to alter sp1 to accept IDList (ID1,ID2,...,IDn), but it is way over my head.
I need help with creating a new SP (lets call it SP2) that accepts IDList,FromDate,ToDate , and then loops with the id list and calls SP1 and union the results.
I hope I am clear...
This is the original SP, If you can make it accept UnitIMEIList it will also be great:
CREATE PROCEDURE [dbo].[GetGeneratorsReport]
#UnitIMEI varchar(15),
#DateFrom [datetime],
#DateTo [datetime]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #mycur CURSOR
DECLARE #GeneratorId int
DECLARE #FieldId int
DECLARE #SensorName nvarchar(50)
DECLARE #StateNO bit
DECLARE #ReadingDate [datetime]
DECLARE #Value bit
DECLARE #FirstRun bit
DECLARE #SDate [datetime]
DECLARE #UnitName nvarchar(50)
--SET #UnitIMEI='358484004085845'
SET #UnitName = (SELECT TOP 1 NickName FROM Vehicles WHERE UnitIEMI = #UnitIMEI)
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#GeneratorsTempTable')) BEGIN DROP TABLE #GeneratorsTempTable END
CREATE TABLE #GeneratorsTempTable (
SensorId int,
UnitIMEI varchar(15),
UnitName nvarchar(50),
SensorName nvarchar(50),
FromDate [datetime],
ToDate [datetime]
)
SET #mycur = CURSOR
FOR
SELECT 104+[GPIO], [Name], [StateNO]
FROM [VehicleTrack].[dbo].[UnitSensors]
WHERE [UnitIMEI]=#UnitIMEI AND Type=3
OPEN #mycur
FETCH NEXT FROM #mycur INTO #FieldId, #SensorName, #StateNO
WHILE ##FETCH_STATUS = 0
BEGIN
SET #FirstRun = 1
SET #SDate = NULL
DECLARE messageCur CURSOR
FOR
SELECT ProtocolMessages.Date, convert(bit, AdditionalReadings.Value) AS Value
FROM ProtocolMessages INNER JOIN
AdditionalReadings ON ProtocolMessages.Id = AdditionalReadings.MessageId
WHERE (ProtocolMessages.UnitIEMI = #UnitIMEI) AND AdditionalReadings.FieldId = #FieldId AND ProtocolMessages.Date >= #DateFrom AND ProtocolMessages.Date <= #DateTo
ORDER BY ProtocolMessages.Date
OPEN messageCur
FETCH NEXT FROM messageCur INTO #ReadingDate, #Value
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#Value > 1)
SET #Value = #Value - 2
IF (#FirstRun = 1 AND #SDate IS NULL)
BEGIN -- the first run
SET #FirstRun = 0 -- flip the bit for all future runs
IF (#Value = #StateNO)
SET #SDate = #ReadingDate
END
ELSE -- all subsequent runs after the first
BEGIN
IF (#SDate IS NULL)
BEGIN
IF (#Value = #StateNO)
SET #SDate = #ReadingDate
END
ELSE
BEGIN
IF (#Value <> #StateNO)
BEGIN
-- Store
INSERT INTO #GeneratorsTempTable ([SensorId], [UnitIMEI], [UnitName], [SensorName] , [FromDate], [ToDate]) VALUES (#FieldId - 104, #UnitIMEI, #UnitName, #SensorName, #SDate, #ReadingDate)
SET #SDate = NULL
END
END
END
FETCH NEXT FROM messageCur INTO #ReadingDate, #Value
END
CLOSE messageCur
DEALLOCATE messageCur
IF (#Value = #StateNO)
BEGIN
INSERT INTO #GeneratorsTempTable ([SensorId], [UnitIMEI], [UnitName], [SensorName] , [FromDate], [ToDate]) VALUES (#FieldId - 104, #UnitIMEI, #UnitName, #SensorName, #SDate, GETUTCDATE())
END
FETCH NEXT FROM #mycur INTO #FieldId, #SensorName, #StateNO
END
DEALLOCATE #mycur
SELECT * FROM #GeneratorsTempTable
END
GO
Thanks
For the benefit of other google users :)
I did it all by myself !
I created a database named 'SandBox' for that.
Create a sample table :
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblStudentGrades](
[StudentGradeID] [bigint] IDENTITY(1,1) NOT NULL,
[StudentID] [bigint] NOT NULL,
[TestID] [bigint] NOT NULL,
[TestDate] [date] NOT NULL,
[TestGrade] [int] NULL
) ON [PRIMARY]
GO
Put some data (If you are lazy:) ) :
USE [SandBox]
GO
SET IDENTITY_INSERT [dbo].[tblStudentGrades] ON
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (1, 1, 1, CAST(0x6E390B00 AS Date), 60)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (2, 1, 2, CAST(0x70390B00 AS Date), 80)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (3, 2, 1, CAST(0x6E390B00 AS Date), 90)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (4, 2, 2, CAST(0x70390B00 AS Date), 100)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (5, 3, 1, CAST(0x6E390B00 AS Date), 95)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (6, 3, 2, CAST(0x0F230100 AS Date), 98)
SET IDENTITY_INSERT [dbo].[tblStudentGrades] OFF
Create the SP that accepts a single id:
* This is just a sample ... don't forget it - I know I can send multiple IDs as a parameter...
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spGetStudentGrades]
#StudentID bigint
AS
BEGIN
SELECT * FROM [SandBox].[dbo].[tblStudentGrades]
WHERE StudentID = #StudentID;
END
GO
Now for the new SP that will allow multiple execution of the above SP (exactly what I was looking for):
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spGetMultiple]
#StudentIDList varchar(100)
AS
BEGIN
DECLARE #StudentID VARCHAR(10)
--------------------------------------------------
-- Create a temporary table to hold the results:
--------------------------------------------------
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tblTemporaryGrades')) BEGIN DROP TABLE #tblTemporaryGrades END
CREATE TABLE #tblTemporaryGrades (
StudentGradeID bigint,
StudentID bigint,
TestID bigint,
TestDate date,
TestGrade int
)
--------------------------------------------------
-- Add a comma to the end of the ID list,
-- so the last ID will be also included.
SET #StudentIDList = #StudentIDList + ',' ;
---------------------------------------------------
WHILE CHARINDEX(',', #StudentIDList) > 0
BEGIN
-- STEP 1 :
-- Extract the current StudentID we want to get from the original SP
SET #StudentID = SUBSTRING(#StudentIDList, 1, ( CHARINDEX(',', #StudentIDList) - 1 ))
PRINT '#StudentID = ' + #StudentID;
-- STEP 2 :
-- Gather the data using the original SP
INSERT INTO #tblTemporaryGrades EXEC spGetStudentGrades #StudentID
-- STEP 3 :
-- Update the student ID to exclude the last StudentID we worked with
SET #StudentIDList = SUBSTRING(#StudentIDList, CHARINDEX(',', #StudentIDList) + 1, LEN(#StudentIDList))
PRINT 'NEW #StudentIDList = ' + #StudentIDList;
END
SELECT * FROM #tblTemporaryGrades
END
GO
Feel like testing it ?
Go ahead:
USE [SandBox]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[spGetMultiple]
#StudentIDList = N'3,2,1'
SELECT 'Return Value' = #return_value
GO
Good luck all !

Create a stored procedure to insert new data into a table

I want to create a stored procedure to insert a new row in a table 'dbo.Terms'
CREATE PROCEDURE dbo.terms
#Term_en NVARCHAR(50) = NULL ,
#Createdate DATETIME = NULL ,
#Writer NVARCHAR(50) = NULL ,
#Term_Subdomain NVARCHAR(50) = NULL
AS
BEGIN
SET NOCOUNT ON
INSERT INTO dbo.terms
(
Term_en ,
Createdate ,
Writer ,
Term_Subdomain
)
VALUES
(
#Term_en = 'Cat' ,
#Createdate = '2013-12-12' ,
#Writer = 'Fadi' ,
#Term_Subdomain = 'English'
)
END
GO
But is shows me an error here ( #Term_en = 'Cat') incorrect syntax
Any help?
I presume you want to insert the values cat etc into the table; to do that you need to use the values from your procedures variables. I wouldn't call your procedure the same name as your table it will get all kinds of confusing; you can find some good resources for naming standards (or crib from Adventureworks)
CREATE PROCEDURE dbo.terms
#Term_en NVARCHAR(50) = NULL ,
#Createdate DATETIME = NULL ,
#Writer NVARCHAR(50) = NULL ,
#Term_Subdomain NVARCHAR(50) = NULL
AS
BEGIN
SET NOCOUNT ON
INSERT INTO dbo.terms
(
Term_en ,
Createdate ,
Writer ,
Term_Subdomain
)
VALUES
(
#Term_en,
#Createdate,
#Writer,
#Term_Subdomain
)
END
GO
And to test it
exec dbo.terms
#Term_en = 'Cat' ,
#Createdate = '2013-12-12' ,
#Writer = 'Fadi' ,
#Term_Subdomain = 'English'
Here is how to set your defaults for parameters in your proc:
CREATE PROCEDURE dbo.terms
#Term_en NVARCHAR(50) = 'Cat',
#Createdate DATETIME = '2013-12-12',
#Writer NVARCHAR(50) = 'Fadi',
#Term_Subdomain NVARCHAR(50) = 'English'
AS
BEGIN
SET NOCOUNT ON
INSERT INTO dbo.terms
(
Term_en ,
Createdate ,
Writer ,
Term_Subdomain
)
VALUES
(
#Term_en,
#Createdate,
#Writer,
#Term_Subdomain
)
END
GO
Your code is not correct.
You put value in insert part. You should enter value in execution part
CREATE PROCEDURE dbo.terms
#Term_en NVARCHAR(50) = NULL ,
#Createdate DATETIME = NULL ,
#Writer NVARCHAR(50) = NULL ,
#Term_Subdomain NVARCHAR(50) = NULL
AS
BEGIN
SET NOCOUNT ON
INSERT INTO dbo.terms
(
Term_en,
Createdate,
Writer,
Term_Subdomain
)
VALUES
(
#Term_en ,
#Createdate ,
#Writer ,
#Term_Subdomain
)
END
execute by this
exec dbo.terms
#Term_en = 'Cat' ,
#Createdate = '2013-12-12' ,
#Writer = 'Fadi' ,
#Term_Subdomain = 'English'
GO
-- =============================================
-- Author: xxxx
-- Create date: xx-xx-xxxx
-- Description: Procedure for Inserting Data in table
-- =============================================
CREATE PROCEDURE [dbo].[SP_Emp_Insert]
(
#Empname nvarchar(250)=null,
#Status int=null,
#LoginUserId nvarchar(50)=null,
#Msg nvarchar(MAX)=null OUTPUT
)
AS
BEGIN TRY
INSERT INTO tbl_Employee
VALUES
(
#Empname ,
#Status,
GETDATE(),
GETDATE(),
#LoginUserId
)
SET #Msg='Table Detail Saved Successfully.'
END TRY
BEGIN CATCH
SET #Msg=ERROR_MESSAGE()
END CATCH
GO

SQL Server trigger's cursor is not working

I created a cursor inside a trigger and it is not working properly. Please help me fix it
Create trigger Posts_Raw_To_Queue_Trigger ON SendNotificationPostsRaw FOR INSERT
AS
BEGIN
DECLARE #PostID uniqueidentifier
DECLARE #UserID uniqueidentifier
DECLARE #ProfID int
DECLARE #Email nvarchar(100)
DECLARE #CreationTime datetime
DECLARE #SpecialityID int
SELECT #ProfID= ProfessionalID,#Email= Email from Professionals where UserID=#UserID
SELECT #PostID = I.PostID,#UserID = I.UserID ,#CreationTime =I.CreationTime FROM INSERTED I
DECLARE post_relation_cursor CURSOR FOR select CategoryId from PostCategoryRelations where PostId=#PostID;
OPEN post_relation_cursor;
FETCH NEXT FROM post_relation_cursor INTO #SpecialityID
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO SendNotificationPostsQueue (UserID,PostID,SpecialityID,TemplateID,CreationTime,SendTime,JSONParameters) Values(#UserID,#PostID,1,1,'04/11/2013','04/11/2013','')
FETCH NEXT FROM post_relation_cursor INTO #SpecialityID;
END;
CLOSE post_relation_cursor;
DEALLOCATE post_relation_cursor;
END
If I remove cursor and insert dummy values into SendNotificationPostsQueue, it works. So there is problem with my cursor... Please tell me why cursor is not working?
It doesn't appear that you need to use a cursor at all and would be better off not using one in almost all cases. Simply replace the body of your trigger (the part between begin and end) with a standard insert:
INSERT INTO SendNotificationPostsQueue (UserID,PostID,SpecialityID,TemplateID,CreationTime,SendTime,JSONParameters)
SELECT
i.UserID,
i.PostID,
1,
1,
'04/11/2013', -- Might want i.CreationTime or current_timestamp
'04/11/2013',
''
FROM INSERTED i
-- possibly want "LEFT JOIN Professionals p on i.UserID = p.UserID" here to grab other info
Note how I am not using the values clause of an insert which can only insert one row. I'm putting a select statement as part of the insert, thus inserting as many rows as the select returns. This means that we don't need to use a cursor, and don't need a bunch of variables to power the cursor.
One issue with your current code, as #automatic has mentioned, is that you're assuming INSERTED only holds one row. If it has more than one, then you'll throw an error when you try to assign a column to a variable.
For reasons of elegance, maintainability, and performance, I strongly urge you to abandon this cursor and run a simple insert (since that's all that your cursor is doing anyway).
Possible problem is here -
CREATE TRIGGER dbo.Posts_Raw_To_Queue_Trigger
ON SendNotificationPostsRaw
-- for view
INSTEAD OF INSERT
-- OR
-- for table
AFTER INSERT
AS BEGIN
DECLARE
#PostID UNIQUEIDENTIFIER
, #UserID UNIQUEIDENTIFIER
, #ProfID INT
, #Email NVARCHAR(100)
, #CreationTime DATETIME
, #SpecialityID INT
SELECT #ProfID = ProfessionalID
, #Email = Email
FROM Professionals
WHERE UserID = #UserID
-- this posible return invalid result (random record from inserted sequence)
SELECT #PostID = I.PostID
, #UserID = I.UserID
, #CreationTime = I.CreationTime
FROM INSERTED I
DECLARE post_relation_cursor CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT CategoryID
FROM dbo.PostCategoryRelations
WHERE PostId = #PostID;
OPEN post_relation_cursor;
FETCH NEXT FROM post_relation_cursor INTO #SpecialityID
WHILE ##FETCH_STATUS=0 BEGIN
INSERT INTO SendNotificationPostsQueue (
UserID
, PostID
, SpecialityID
, TemplateID
, CreationTime
, SendTime
, JSONParameters
)
SELECT
#UserID
, #PostID
, #SpecialityID --- !!!
, 1
, '04/11/2013'
, '04/11/2013'
, ''
FETCH NEXT FROM post_relation_cursor INTO #SpecialityID;
END;
CLOSE post_relation_cursor;
DEALLOCATE post_relation_cursor;
END
Update
If I understand you correctly, the business logic must be like this:
CREATE TRIGGER dbo.Posts_Raw_To_Queue_Trigger
ON dbo.SendNotificationPostsRaw
[INSTEAD OF]/[AFTER] INSERT
AS BEGIN
SET NOCOUNT ON;
DECLARE
#PostID UNIQUEIDENTIFIER
, #UserID UNIQUEIDENTIFIER
, #ProfID INT
, #Email NVARCHAR(100)
, #CreationTime DATETIME
, #SpecialityID INT
DECLARE cur CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT
i.PostID
, i.UserID
, ProfID = p.ProfessionalID
, p.Email
, i.CreationTime
, pcr.CategoryID
FROM INSERTED i
JOIN dbo.Professionals p ON i.UserID = p.UserID
JOIN dbo.PostCategoryRelations pcr ON i.PostID = pcr.PostID
OPEN cur
FETCH NEXT FROM cur INTO
#PostID
, #UserID
, #ProfID
, #Email
, #CreationTime
, #SpecialityID
WHILE ##FETCH_STATUS = 0 BEGIN
INSERT INTO dbo.SendNotificationPostsQueue
(
UserID
, PostID
, SpecialityID
, TemplateID
, CreationTime
, SendTime
, JSONParameters
)
SELECT
#UserID
, #PostID
, #SpecialityID
, 1
, #CreationTime
, #CreationTime
, ''
FETCH NEXT FROM cur INTO
#PostID
, #UserID
, #ProfID
, #Email
, #CreationTime
, #SpecialityID
END
CLOSE cur
DEALLOCATE cur
END

stored procedure with insert & update using identity column

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.