Хранимые процедуры SQL Server для INSERT и UPDATE, лучше разделить или сжать? - PullRequest
7 голосов
/ 28 июля 2011

Я создаю хранимые процедуры для вставки и обновления данных в моей базе данных SQL Server.Сначала я создавал отдельную процедуру для Add / Set, но потом наткнулся на запрос, который позволяет мне объединить их в одну процедуру.Я хотел бы узнать у сообщества SO о возможных проблемах в будущем, делая это таким образом.

Отдельные процедуры

--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

Объединено

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

Пока у меня есть 15 таблиц типов, для которых я создаю процедуры, и пытаюсь сократить количество созданных процедур, однако я не хочу жертвовать производительностью.Я знаю, что второй метод - это больше обработки, но будет ли он достаточно значительным, чтобы вызвать проблемы?Я не вижу таблиц типов, содержащих массовые объемы данных, не более 100 записей со средним значением около 10-20.

Любые мысли и предложения приветствуются.

Ответы [ 2 ]

13 голосов
/ 28 июля 2011

Какая версия SQL Server? Эта информация всегда полезна, поэтому, пожалуйста, пометьте свой вопрос конкретной версией.

Если или выше, вы можете рассмотреть MERGE вместо отдельных операций INSERT / UPDATE, хотя с момента написания этого ответа я определенно изменил мою мелодию и предпочел методологию UPDATE / IF @@ROWCOUNT = 0 / INSERT, которую вы предложили. Для получения дополнительной информации см. Эту статью, которую я написал:

Вот пример MERGE (запустите его в базе данных tempdb), но я снова рекомендую против него вообще.

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

Затем процедура:

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

Теперь давайте запустим его и проверим результаты:

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

Очистить:

DROP TABLE dbo.DataType;
DROP PROCEDURE dbo.MergeDataType;
0 голосов
/ 08 февраля 2018
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...