哪种是有效的?向存储过程发送多个参数或从SQL处理单个xml

本文关键字:参数 SQL xml 单个 处理 有效 存储过程 | 更新日期: 2023-09-27 18:10:48

哪个更有效率?假设我需要从前端代码中插入值到单个或多个表中,哪种做法更好?将每个参数逐一直接发送给存储过程并执行;或使用一个适度的过程,接受参数为xml,并通过发送从xml派生的参数来执行所需的过程;在这种情况下,我们只发送参数值,参数名保持在适中的功能。

哪种是有效的?向存储过程发送多个参数或从SQL处理单个xml

我希望单独的参数方法执行得更好。这不仅可以消除服务器端的XML解析开销,还可以提供一个定义良好的数据库接口。

保持简单愚蠢的伙伴。这是我在审查PR时对我的一个开发者的回答。当你必须阅读它或发现错误时,将参数传递给SP是一场彻头彻尾的噩梦。想象一下,xml中有15个以上的参数,所有的序列化都只是为了返回一个固定的数据结构。在某些场景中可能需要这种解决方案,但是当您考虑到开发和维护这种存储过程是多么耗时和昂贵时,就不应该采用这种方法。紧耦合、可伸缩性也是需要考虑的问题。如果您的目标是在SP中使用动态参数,请考虑以下方法:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_ReviewSearch]
    @Ids nvarchar(max),
    @Identifiers nvarchar(max),
    @Pnr nvarchar(10),
    @HotelId bigint,
    @PassengerEmail nvarchar(50),
    @ReviewStatus nvarchar(20),
    @Deleted bit = null,
    @CompletedUtcFrom datetime,
    @CompletedUtcTo datetime,
    @HotelStayEndUtcFrom datetime,
    @HotelStayEndUtcTo datetime
AS
    SELECT Id, Identifier, Pnr, DebtorIdentifier, HotelId, PassengerEmail, UserFullName, OverallRating, 
                CreatedUtc, HotelStayStartUtc, HotelStayEndUtc, TravelerNotifId, TravelerNotifSentNumber, TravelerNotifSentUtc, 
                CompletedUtc, ApprovalNotifId, ApprovalNotifSentNumber, ApprovalNotifSentUtc, ApprovedUtc, ApprovedBy, ReviewStatus, Deleted
    FROM     Review
    WHERE  (@Ids IS NULL OR Id IN (SELECT Item FROM Split(@Ids, ','))) AND 
                    (@Identifiers IS NULL OR Identifier IN (SELECT Item FROM Split(@Identifiers, ','))) AND 
                    (@Pnr IS NULL OR Pnr = @Pnr) AND 
                    (@HotelId IS NULL OR HotelId = @HotelId) AND 
                    (@PassengerEmail IS NULL OR PassengerEmail = @PassengerEmail) AND 
                    (@ReviewStatus IS NULL OR ReviewStatus IN (SELECT Item FROM Split(@ReviewStatus, ','))) AND 
                    (@Deleted IS NULL OR Deleted = @Deleted) AND
                    (@CompletedUtcFrom IS NULL OR CompletedUtc >= @CompletedUtcFrom) AND
                    (@CompletedUtcTo IS NULL OR CompletedUtc <= @CompletedUtcTo) AND
                    (@HotelStayEndUtcFrom IS NULL OR HotelStayEndUtc >= @HotelStayEndUtcFrom) AND
                    (@HotelStayEndUtcTo IS NULL OR HotelStayEndUtc <= @HotelStayEndUtcTo)