jon3laze
jon3laze

Reputation: 3196

SQL Server stored procedures for INSERT and UPDATE, better to separate or condense?

I am creating stored procedures for inserting and updating data in my SQL Server database. At first I was creating a separate procedure for Add/Set but then I stumbled across a query that allows me to condense them into a single procedure. I wanted to check with the SO community on any possible future issues doing it this way.

Separate Procedures

--INSERT Procedure
CREATE PROCEDURE [dbo].[AddDataType]
    @TypeName [nvarchar](255),
    @TypeProperty [nvarchar](255)
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO DataType(TypeName, TypeProperty)
    VALUES(@TypeName, @TypeProperty)

    SELECT SCOPE_IDENTITY()
END

--UPDATE Procedure
CREATE PROCEDURE [dbo].[SetDataType]
    @ID [int],
    @TypeName [nvarchar](255),
    @TypeProperty [nvarchar](255)
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE DataType SET TypeName = @TypeName, TypeProperty = @TypeProperty
    WHERE ID = @ID
 END

EXEC AddDataType @TypeName = 'Test Name', @TypeProperty = 'Test Property' --INSERT
EXEC SetDataType @ID = 42, @TypeName = 'Test Name', @TestProperty = 'Test Property' --UPDATE

Combined

CREATE PROCEDURE [dbo].[SetDataType]
    @ID [int] = NULL,
    @TypeName [nvarchar](255),
    @TypeProperty [nvarchar](255)
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE DataType SET TypeName = @TypeName, TypeProperty = @TypeProperty
    WHERE ID = @ID

    IF @@ROWCOUNT = 0
        INSERT INTO DataType(TypeName, TypeProperty)
        VALUES(@TypeName, @TypeProperty)

    IF @ID IS NULL
        SELECT SCOPE_IDENTITY()
END

EXEC SetDataType @TypeName = 'New Type Name', @TypeProperty = 'New Type Property' --INSERT
EXEC SetDataType @ID = 42, @TypeName = 'Updated Type Name', @TypeProperty = 'Updated Type Property' --UPDATE

So far I have 15 type tables that I creating procedures for and am trying to cut down on the number of procedures created, however I don't want to sacrifice performance. I know the second method is more processing, but would it be significant enough to cause issues? I don't see the type tables holding mass amounts of data, no more than 100 records with the average being around 10-20.

Any thoughts or suggestions are appreciated.

Upvotes: 7

Views: 92687

Answers (2)

Aaron Bertrand
Aaron Bertrand

Reputation: 280330

What version of SQL Server? This information is always useful so please get in the habit of tagging your question with the specific version.

If or greater, you might consider MERGE instead of separate INSERT/UPDATE operations, though since writing this answer I have definitely changed my tune and prefer the UPDATE / IF @@ROWCOUNT = 0 / INSERT methodology you proposed. For more info, see:

Here is a MERGE sample (run it in tempdb), but again I recommend against it in general.

CREATE TABLE dbo.DataType
(
    ID             int IDENTITY(1,1),
    TypeName       nvarchar(255),
    [TypeProperty] nvarchar(255),
    CONSTRAINT PK_DataType PRIMARY KEY (ID)
);

INSERT dbo.DataType(TypeName, [TypeProperty]) VALUES (N'name 1', N'property 1');
GO

Then a procedure:

CREATE PROCEDURE dbo.MergeDataType
    @ID           int = NULL,
    @TypeName     nvarchar(255),
    @TypeProperty nvarchar(255)
AS
BEGIN
    SET NOCOUNT ON;

    WITH [source](ID, TypeName, [TypeProperty]) AS 
    (
        SELECT @ID, @TypeName, @TypeProperty
    )
    MERGE dbo.DataType WITH (HOLDLOCK) AS [target] 
      USING [source] ON [target].ID = [source].ID
    WHEN MATCHED THEN
        UPDATE SET [target].TypeName       = @TypeName,
                   [target].[TypeProperty] = @TypeProperty
    WHEN NOT MATCHED THEN
        INSERT (TypeName, [TypeProperty]) 
        VALUES (@TypeName, @TypeProperty);
END
GO

Now let's run it and check the results:

EXEC dbo.MergeDataType 
    @TypeName     = N'foo', 
    @TypeProperty = N'bar';

EXEC dbo.MergeDataType 
    @ID           = 1, 
    @TypeName     = N'name 1', 
    @TypeProperty = N'new property';
GO

SELECT ID, TypeName, [TypeProperty] FROM dbo.DataType;
GO

Clean up:

DROP TABLE dbo.DataType;
DROP PROCEDURE dbo.MergeDataType;

Upvotes: 15

manoj garu
manoj garu

Reputation: 163

USE [//Your Database Name]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[InsertIcone] 
    -- Add the parameters for the stored procedure here
(
@amount decimal(18,0),
@payer  nvarchar(50),
@paymentMode  nvarchar(50),
@date date,
@description nvarchar(Max),
@operatorId int
)
AS
begin
if exists (select *  from wallet2 as t where payer=@payer)
begin
    update wallet2 set amount=@amount,payer=@payer,paymentMode=@paymentMode,
    [date]=@date,[description]=@description where id=(select id  from 
    wallet2 as t where payer=@payer) and operatorId=@operatorId
end
else 
begin
         insert into dbo.Wallet2 
         values(@amount,@payer,@paymentMode,@date,@description,@operatorId);
    end

END

Upvotes: -1

Related Questions