Инкапсуляция логики в SQL - лучшие практики - PullRequest
0 голосов
/ 23 сентября 2011

Привет и спасибо за чтение!

Мне было интересно, как лучше всего инкапсулировать логику хранимых процедур с использованием метода SQL на основе множеств.

Например, у меня есть приложение для ввода продукта, которое я разрабатываю. Пытаясь ограничить дублирование кода, я создал хранимую процедуру AddItem, которая создает новый продукт в таблицах продуктов. Недостатком является то, что для использования этой процедуры в ситуации, которая требует добавления группы продуктов, я вынужден использовать курсор или цикл WHILE для выполнения процедуры по типу «FOR EACH». Это приводит к очень низкой производительности на больших наборах предметов.

Конечно, я мог бы жестко закодировать операторы INSERT в вызывающей процедуре, но это заставляет меня чувствовать себя странно, потому что весь смысл в том, чтобы иметь возможность изменить (в одном месте) логику «добавления элемента». Поэтому, если столбец изменился, я должен был помнить, чтобы изменить все операторы INSERT во всех местах, которые его используют. Я просто подумал, что должен быть лучший способ сделать это, и любой совет будет оценен.

EDIT: Совершенно верно, я должен привести пример кода. Вот содержимое процедуры AddItem, которая выполняется в базе данных MS SQL2005:

            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 продуктов занимает более минуты, и от этого становится только хуже.

EDIT: Чтобы дополнительно прояснить решение, приложение позволяет элементы, которые имеют отношения родитель-ребенок. При добавлении нового родительского элемента пользователь выбирает из списка параметров, и набор дочерних элементов создается на основе набора параметров.

Например, пользователь может создать продукт под названием «Awesome Boot» с набором опций Colors = "Brown, Black", Size = "10M, 11M, 12M", ToeStyle = "SteelToe, SoftToe" - это будет создать набор из 12 предметов. Очевидно, вы можете увидеть, как это может возрасти в геометрической прогрессии, учитывая, что большинство ботинок имеют около 36 размеров, несколько цветов и стилей ног, а также другие варианты. Это может привести к родительскому элементу с большим количеством дочерних элементов.

Я полагаю, что одним из решений было бы объединение всей информации об элементах в одну таблицу "Элементы", что устраняет необходимость хранения одной и той же IDENTITY в нескольких таблицах. Мне нравится удобство логического разделения связанных данных на разные таблицы. Может быть, я пытаюсь взять свой пирог и съесть его тоже!

Спасибо! :)

1 Ответ

0 голосов
/ 23 сентября 2011

Это просто случайный комментарий - две таблицы ItemWebInfo и ItemTags - если в этих таблицах в конечном итоге не будет нескольких строк на сущность, я думаю, что это будет иметь гораздо больший смысл (по крайней мере в большинстве случаев - всегда есть исключения)эти столбцы были в основной таблице.Я также мог бы предложить то же самое для supplierInfo, за исключением случаев, когда элемент может иметь более одного поставщика, а supplierID также должен быть просто столбцом в первичной таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...