2009-08-09 3 views
1

Мне нужно обновить несколько строк в таблице Parts, когда изменится поле в другой таблице, и я хочу использовать триггер. Причиной запуска является много существующих приложений и изменение данных, и у меня нет доступа ко всем из них. Я знаю, что некоторые базы данных поддерживают строку «Для каждой строки» в триггерном выражении, но я не думаю, что Microsoft делает это.Триггеры SQL Server «Для каждой строки» эквивалент

У меня есть два стола Детали и категории.

частей имеет часть #, CATEGORY_ID, part_name оригинальный и много других вещей

Категория имеет CATEGORY_ID и category_name.

Оригинал представляет собой конкатенацию category_name и part_name разделенных символом «:»

Например Браслеты: BB129090

Если кто-то изменяет category_name (для excample от браслетов до браслетов), Оригинала поле должно быть обновляется в каждой строке таблицы Parts. Хотя это нечастое событие, это бывает достаточно, чтобы вызвать проблемы.

Нет Веб и десктоп приложения использует первоначально

Всего использования приложений учета только оригинал

Это моя задача вести бухгалтерский учет и другие приложения в синхронизации.

Я не проектировал базу данных, и компания, которая написала бухгалтерскую программу, не изменит ее.

ответ

1

Я предполагаю, что в вашем случае нет необходимости в триггере уровня строки.

Вы можете сделать что-то вроде

IF UPDATE(Category_Name) 
    UPDATE Parts 
    SET Original = inserted.Category_Name + ':' + Part_Name 
    FROM Parts 
    INNER JOIN inserted ON Parts.Category_ID = inserted.Category_ID 

как UPDATE триггер на таблицу категорий.

Если вам действительно нужна обработка каждой строки (скажем, хранимой процедуры), вам понадобится цикл CURSOR или WHILE.

+0

ИФ UPDATE (Original) никогда не будет k - столбец «Оригинал» никогда не будет обновлен, не так ли? Это столбец Category_Name или столбец Part_Name, который может быть обновлен, и затем запускает обновление столбца «Оригинал» –

+0

Plus, вам также нужен триггер в таблице «Parts», если изменяется столбец «Part_name» - триггер только на в таблице категорий недостаточно –

+0

Исправлена ​​категория_имя. ваш вопрос фокусируется на Category_Name, поэтому я набросал решение для Category_Name. Конечно, вам также нужна аналогичная функциональность в триггере обновления для частей – devio

0

Если вы можете изменить схемы таблиц, на вариант, который вы бы, что бы гарантировать, что Original столбец всегда в актуальном состоянии, независимо от того, что, не сделать Original вычисляемый столбец - столбец, который вычисленный из category_name плюс Part_Name по мере необходимости.

Для этого вам нужно создать хранимую функцию, которая будет делать это вычисление для вас - что-то вроде этого:

CREATE FUNCTION dbo.CreateOriginal(@Category_ID INT, @Part_Name VARCHAR(50)) 
RETURNS VARCHAR(50) 
WITH SCHEMABINDING 
AS BEGIN 
    DECLARE @Category_Name VARCHAR(50) 

    SELECT @Category_Name = Category_Name FROM dbo.Category 
     WHERE Category_ID = @Category_ID 

    RETURN @Category_Name + ': ' + @Part_Name 
END 

, а затем вам нужно добавить столбец в Parts таблицу, которая покажет результат этой функции для каждой строки в таблице:

ALTER TABLE Parts 
    ADD Original AS dbo.CreateOriginal(Category_ID, Part_Name) 

Основным недостатком является тот факт, что для отображения значения столбца, то функция должна вызываться каждый раз, для каждой строки.

С другой стороны, ваши данные всегда актуальны и всегда гарантированно верны, несмотря ни на что. Не требуется никаких триггеров.

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

Марк

1

Оригинальная колонка нарушает 1nf, что является очень плохой идеей. Вы можете либо

  1. Пропустите колонку полностью и объедините ее в каждом запросе (возможно, это не лучшее решение, но я утверждаю, что это, вероятно, лучше, чем триггер).
  2. Создайте представление по таблице и получите исходный столбец в представлении (возможно, что я буду делать), или
  3. Сделать оригинал вычисленным столбцом, что является лучшим способом, если вы хотите создать на нем индекс.
+0

, зависит от вашего определения 1NF - mine «не содержит нескольких значений в одном поле», и это не подтверждено, IMO –

+1

Mine «не содержит нескольких значения в одном поле "и" не содержит одну и ту же информацию в нескольких полях ". – erikkallen

2

Или другой вариант: почему бы вам не просто создать вид этих двух таблиц, для бухгалтерии, которая содержит этот каскадный столбец:

CREATE VIEW dbo.AccountingView 
AS 
    SELECT 
    p.PartNo, p.Part_Name, p.Category_ID, 
    c.Category_Name + ':' + p.PartName as 'Original' 
    FROM 
    Parts p 
    INNER JOIN 
    Category c ON p.Category_ID = c.Category_ID 

Теперь ваши бухгалтерские люди могут использовать этот вид для их представления, это всегда свежие, всегда в актуальном состоянии, и вам не придется беспокоиться об обновлении и вставки триггеров и все эти сложные вещи .....

Марк

Смежные вопросы