#node.js #sql-server #triggers
#node.js #sql-сервер #триггеры
Вопрос:
У меня есть приложение nodejs с SQL Server. Я хочу иметь возможность обновлять таблицу для «конкретной организации» на основе действия вставки и удаления. Допустим, у меня есть 2 таблицы следующим образом:
- Проект: projId, OrgID, projName
- Задачи: идентификатор задачи, идентификатор проекта, имя задачи
- Пользователи: идентификатор пользователя, идентификатор организации, имя пользователя
- ОрганизациясТатьи: количество проектов, количество пользователей, количество задач OrgID
Итак, допустим, я добавляю новый проект для организации, где OrgID = 1. Моя инструкция insert из Nodejs будет:
insert into project (projId, orgId, projName)
values (${'projId'}, ${'orgId'}, 'New Project');
Я хочу написать триггер в SQL Server, который добавляет 1 к numberOfProjects
столбцу с orgId
переданным значением.
create trigger updateProjectAfterInsert
on project
after insert
as
begin
update OrganizationStats
set numprojects = numberOfProjects 1
where orgId = 'THE_INSERTED_ORGID_VALUE';
end;
Моя проблема в том, что я не знаю, как передать ${'orgId'}
триггеру.
Комментарии:
1. Используйте вставленные / удаленные псевдотаблицы.
2. Вы также предполагаете, что количество вставленных строк всегда равно 1 — распространенная ошибка. Но зачем вообще это делать? Значение можно легко определить, подсчитав связанные строки, когда это необходимо, и оно ВСЕГДА будет правильным. Вы забыли об удалениях? Можно ли перемещать проект между организациями?
3. Лично я не рекомендую хранить значения, которые могут быть вычислены с помощью агрегата. Если вам нужна такая информация, легко доступная, вам лучше сделать a
VIEW
со значением там, на мой взгляд.
Ответ №1:
Я собираюсь расширить свой комментарий здесь:
Лично я не рекомендую хранить значения, которые могут быть вычислены с помощью агрегата. Если вам нужна такая информация, легко доступная, вам лучше создать представление со значением там, на мой взгляд.
Под этим я подразумеваю, что NumProjects
в таблице «нет права» OrganizationStats
, вместо этого оно должно вычисляться в то время, когда требуется информация. Вы не можете использовать агрегатную функцию в определении вычисляемого столбца без скалярной функции, и они могут быть довольно медленными. Вместо этого я рекомендую создать VIEW
(или, если вы предпочитаете функцию табличного значения), чтобы предоставить вам информацию из таблицы:
CREATE VIEW dbo.vw_OrganisationStats AS
SELECT {Columns from OrganizationStats},
P.Projects AS NumProjects
FROM dbo.OrganizationStats OS
CROSS APPLY (SELECT COUNT(*) AS Projects
FROM dbo.Projects P
WHERE P.OrgID = OS.OrgID) P;
Я использую a CROSS APPLY
с подзапросом, так как тогда вам не нужен огромный GROUP BY
в конце.
Комментарии:
1. Итак, учитывая вышеизложенное, нужно ли мне создать еще 2 представления для вычисления количества numberOfUsers и numberOfTasks, или другие два столбца могут быть вычислены в том же представлении?
2. Вы бы добавили в то же представление.
3. итак, учитывая структуру таблицы в исходном вопросе, я не уверен, что все они попадут в один запрос представления.. @Lamu Не могли бы вы помочь с примером кода?
4. «Не могли бы вы помочь с примером кода?» В моем вопросе есть один, @SeanD . Я не знаю вашего дизайна или деталей требований, которые не рассматриваются в вопросе, но вы, безусловно, можете использовать несколько агрегатных функций в одном
VIEW
. Если вы не знаете, как реализовать вышеизложенное, вам лучше задать новый вопрос, так как в конечном итоге вы аннулируете оба ответа здесь, если измените этот вопрос.
Ответ №2:
Я думаю, что вы хотите, чтобы это было что-то вроде этого:
CREATE TRIGGER updateProjectAfterInsert
ON Project
AFTER INSERT
AS
BEGIN
UPDATE OrganizationStats
SET NumProjects = NumProjects 1
WHERE OrgId IN (SELECT OrgId FROM inserted);
END;
Также обратите внимание, что триггеры всегда должны принимать несколько строк. Можно вставить несколько строк, обновить несколько строк и удалить несколько строк. «Вставленные» и «удаленные» коллекции содержат необходимые данные («вставленные» содержат вставляемые строки, «удаленные» содержат удаляемые строки, а при обновлении «вставленные» содержат значения после обновления, а «удаленные» содержат значения до обновления).
Комментарии:
1. Обратите внимание, что если 2 проекта для одной и той же организации вставляются одновременно, это будет работать, но не так, как ожидает OP.
2. Hrm, да, если это возможный случай, то » 1″, скорее всего, должно быть вычислено с помощью коррелированного подзапроса.
3. Передается OrgID. в принципе, та же логика должна работать для удаленных значений, мне нужно вычесть единицу из столбца.
4.
AFTER INSERT
триггеры не возникают послеDELETE
@SeanD .5. Добавьте еще один триггер AFTER DELETE для обработки удалений, @SeanD