在SQL中封装逻辑 - 最佳实践

时间:2011-09-23 13:24:46

标签: sql sql-server-2005

问候和感谢阅读!

我想知道使用基于集合的SQL技术封装存储过程逻辑的最佳实践是什么。

例如,我有一个我正在开发的产品输入应用程序。在尝试限制代码重复时,我创建了一个名为AddItem的存储过程,它在产品表中创建了一个新产品。缺点是,为了在需要添加一组产品的情况下利用此过程,我不得不使用游标或WHILE循环以“FOR EACH”类型的方式执行该过程。这导致大型物品的性能非常差。

当然我可以将INSERT语句硬编码到调用过程中,但这让我觉得很蠢,因为重点是能够(在一个地方)改变“添加项”逻辑。因此,如果列发生了更改,我必须记住在所有使用它的地方更改所有INSERT语句。我只是觉得必须有更好的方法来做这件事,任何建议都会受到赞赏。

编辑: 非常正确,我应该提供一个代码示例。以下是在MS SQL2005数据库上执行的AddItem过程的内容:

            ALTER PROCEDURE [dbo].[AddItem]
                @ProjectNumber  int,
                @ItemName       varchar(255),
                @SupplierID     int,
                @SKUType        int,
                @Store          varchar(3),
                @Category       varchar(4),
                @AddedBy        varchar(255),
                @ParentSKU      varchar(255) = NULL,
                @SetNumber      int = NULL,
                @NewItemNumber  int OUTPUT
            AS  
                SET NOCOUNT ON

                DECLARE @DiscontinuedStatus bit

                BEGIN TRY
                    BEGIN TRAN
                        SET @NewItemNumber = 0

                        INSERT INTO ProductEntry.dbo.Items
                        (ProjectNumber, SetNumber, SKUType, Store, Category, AddedBy, ParentSKU, EntryTime)
                        VALUES(@ProjectNumber, @SetNumber, @SKUType, @Store, @Category, @AddedBy, @ParentSKU, CURRENT_TIMESTAMP)

                        SET @NewItemNumber = SCOPE_IDENTITY()

                        IF @SKUType = 1
                        BEGIN
                            SET @DiscontinuedStatus = 1
                        END
                        ELSE
                        BEGIN
                            SET @DiscontinuedStatus = 0
                        END 

                        INSERT INTO ProductEntry.dbo.ItemInfo
                        (ItemNumber, ItemName, Discontinued)
                        VALUES (@NewItemNumber, @ItemName, @DiscontinuedStatus)

                        INSERT INTO ProductEntry.dbo.ItemSupplierInfo   
                        (ItemNumber, SupplierID)
                        VALUES(@NewItemNumber, @SupplierID)

                        INSERT INTO ProductEntry.dbo.ItemWebInfo
                        (ItemNumber)
                        VALUES(@NewItemNumber)

                        INSERT INTO ProductEntry.dbo.ItemTags
                        (ItemNumber)
                        VALUES (@NewItemNumber)
                    COMMIT TRAN
                END TRY
                BEGIN CATCH
                    ROLLBACK TRAN
                END CATCH

我需要一个一次添加多个项目(数字大于1000)的过程,并且在使用游标时性能非常糟糕。添加一组800个产品需要一分多钟,而且只会从那里变得更糟。

编辑: 为了进一步阐明解决方案,应用程序允许具有父子关系的项目。添加新父项时,用户从选项列表中进行选择,并根据选项集生成一组子项。

例如,用户可以创建一个名为“Awesome Boot”的产品,其选项设置为Colors =“Brown,Black”,Size =“10M,11M,12M”,ToeStyle =“SteelToe,SoftToe” - 这样会生成一组12个项目。显然,考虑到大多数靴子有大约36种尺码,多种颜色和鞋头款式,以及其他选项,你可以看到它会如何呈指数级增长。这可能导致父项具有大量子项。

我想一种解决方案是将所有不同的项目信息合并到一个“项目”表中,从而无需在多个表中存储相同的IDENTITY。我有点喜欢将相关数据逻辑分成不同表格的便利。也许我正试着吃蛋糕然后吃它!

谢谢! :)

1 个答案:

答案 0 :(得分:0)

这只是一个流浪的评论 - 两个表ItemWebInfo和ItemTags - 除非这些表最终每个实体有多个行,我认为它会更有意义(至少在大多数情况下 - 总有例外),如果那些列在主表中。我也可能对supplierInfo提出相同的建议,除非一个项目可以有多个供应商,所以supplierID也应该只是主表中的一列。