SQL Server запускает эквивалент «Для каждой строки» - PullRequest
1 голос
/ 10 августа 2009

Мне нужно обновить несколько строк в таблице «Части», когда поле в другой таблице изменяется, и я хочу использовать триггер. Причиной триггера является то, что многие существующие приложения используют и изменяют данные, и у меня нет доступа ко всем из них. Я знаю, что некоторые базы данных поддерживают оператор For Each Row в выражении триггера, но я не думаю, что Microsoft поддерживает.

Конкретно у меня есть две таблицы Части и Категории.

Детали имеют Part #, Category_ID, Part_Name и Original и много других вещей

Категория имеет Category_ID и Category_name.

Оригинал - это объединение Category_Name и Part_Name, разделенных ':'

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

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

Нет веб-приложений и приложений для настольных компьютеров, использующих Original

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

Моя задача - синхронизировать бухгалтерию и другое приложение.

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

Ответы [ 4 ]

2 голосов
/ 12 августа 2009

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

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

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

Марк

1 голос
/ 10 августа 2009

Исходный столбец нарушает 1NF, что является очень плохой идеей. Вы можете либо

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

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

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

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 голосов
/ 10 августа 2009

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

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

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

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

Марк

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