Отношение мастер / деталь в T-SQL - PullRequest
1 голос
/ 31 октября 2011

В обычной базе данных t-sql, ориентированной на создание заказов, я заметил, что есть несколько таблиц (например, Заголовок заказа и Строки заказа), для которых в базе данных не определены реальные противоречия. Есть ли недостаток в определении этого ограничения? Кажется, это предотвратило бы осиротевшие записи ...

обновление: одна из причин, которые я спрашиваю, состоит в том, что в хранимых процедурах, которые создают структуры Заголовок заказа / Строка заказа, есть фрагменты кода, подобные этому:

SELECT  @sc_count = COUNT(*)
FROM    shopping_cart
WHERE   session_id = @sessionid 

INSERT  INTO log_table
        ( col1 ,
          col2 ,
          col3 ,
          col4 ,
          col5 ,
          col6 
        )
VALUES  ( 'load config' ,
          'count before' ,
          @sc_count ,
          @sessionid ,
          @quoteid ,
          @login_name 
        ) 

DECLARE @quote_product_id UNIQUEIDENTIFIER
DECLARE cart_cur CURSOR
FOR
    SELECT  quote_product_id
    FROM    quote_products
    WHERE   quote_id = @quoteid
OPEN cart_cur
FETCH NEXT FROM cart_cur INTO @quote_product_id

WHILE @@fetch_status = 0 
    BEGIN
        INSERT  INTO log_table
                ( col1 ,
                  col2 ,
                  col3 ,
                  col4 ,
                  col5
                )
        VALUES  ( 'load cart' ,
                  @sessionid ,
                  @quoteid ,
                  'checking product' ,
                  @quote_product_id
                )
        IF NOT EXISTS ( SELECT  session_product_id
                        FROM    shopping_cart
                        WHERE   session_product_id = @quote_product_id ) 
            BEGIN

                BEGIN TRY
                    INSERT  INTO shopping_cart
                            ( session_product_id ,
                              session_id ,
                              product_dim_id ,
                              quantity ,
                              price ,
                              picked_by_user ,
                              category_id ,
                              kit_id ,
                              price_list_id ,
                              configuration_id ,
                              origin_by ,
                              origin_date ,
                              changed_by ,
                              change_date ,
                              from_product ,
                              base_category_id ,
                              discount ,
                              discount_amount
                        )
                            SELECT  quote_product_id ,
                                    @sessionid ,
                                    product_dim_id ,
                                    quantity ,
                                    unit_price ,
                                    picked_by_user ,
                                    category_id ,
                                    kit_id ,
                                    price_list_id ,
                                    configuration_id ,
                                    origin_by ,
                                    origin_date ,
                                    changed_by ,
                                    change_date ,
                                    from_product ,
                                    NULL,
                                    discount ,
                                    discount_amount

                            FROM    quote_products
                            WHERE   quote_product_id = @quote_product_id
                END TRY
                BEGIN CATCH
                    DECLARE @error_number INT
                    DECLARE @error_message NVARCHAR(2048)
                    SELECT  @error_number = ERROR_NUMBER() ,
                            @error_message = ERROR_MESSAGE()

                    DELETE  FROM shopping_cart_header
                    WHERE   session_id = @sessionid
                    INSERT  INTO log_table
                            ( col1 ,
                              col2 ,
                              col3 ,
                              col4 ,
                              col_max
                            )
                    VALUES  ( 'dm load cart error - CATCH' ,
                              @sessionid ,
                              @quoteid ,
                              @error_number ,
                              @error_message
                            )

                    SELECT  @kitid AS kit_id ,
                            @pricelistid AS price_list_id ,
                            NEWID() AS configuration_id ,
                            0 AS cart_number_of_products ,
                            1 AS quote_number_of_products

                    RETURN 
                END CATCH

            END 
        ELSE 
            BEGIN
                UPDATE  shopping_cart
                SET     session_id = @sessionid
                WHERE   session_product_id = @quote_product_id
            END

        FETCH NEXT FROM cart_cur INTO @quote_product_id
    END

CLOSE cart_cur
DEALLOCATE cart_cur

SELECT  @sc_count = COUNT(*)
FROM    shopping_cart
WHERE   session_id = @sessionid 
INSERT  INTO log_table
        ( col1 ,
          col2 ,
          col3 ,
          col4 ,
          col5 ,
          col6 
        )
VALUES  ( 'load config' ,
          'count after' ,
          @sc_count ,
          @sessionid ,
          @quoteid ,
          @login_name 
        )

Кажется, хранимая процедура пытается определить неверное состояние, когда quote_product_id возвращает больше строк из одного критерия предложения WHERE, чем из другого. Существует комментарий, в котором, по сути, говорится, что цитата может быть сохранена неправильно, и теперь ее необходимо проверить, чтобы убедиться, что все продукты (строки) котировки присутствуют и учитываются.

1 Ответ

2 голосов
/ 31 октября 2011

Я могу придумать две возможные причины, но я уверен, что есть еще много:

  1. Ограничение ссылочной целостности может повлиять на производительность. Это не означает, что их не следует использовать или включать (если только после тщательного профилирования вы не решите, что это действительно так).
  2. Порядок вставки не позволяет сохранить ограничение. Отсутствие ограничений по этой причине является рискованным предложением, поскольку база данных может иногда находиться в недопустимом состоянии, если только все такие действия тщательно не поддерживаются в транзакциях, в результате чего база данных остается действительной в конце каждой транзакции.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...