#sql #sql-server
#sql #sql-сервер
Вопрос:
Итак, я пытаюсь создать триггер, который обновит столбец, вызываемый TOTAL_CURSOS
из моей таблицы TOTALES
, с количеством доступных курсов. Триггер произойдет, когда я вставлю значение в свою таблицу CURSO
. Проблема, с которой я сталкиваюсь, связана с моими int
значениями DURACION
и. COSTO
Вот мой код триггера:
CREATE TRIGGER [TR_CURSO] ON [CURSO] FOR INSERT
AS
UPDATE
TOTALES
SET
TOTAL_CURSOS = ( SELECT COUNT(CODIGO) FROM CURSO );
INSERT INTO BITACORA (
MOMENTO,
DESCRIPCION
)
VALUES (
SYSDATETIME(),
'SE INSERTO EL MAESTRO CON RFC DE: '
(SELECT RFC_I FROM INSERTED)
' DEL CURSO: '
(SELECT NOMBRE FROM INSERTED)
' CON COSTO DE: '
CAST(COSTO AS nvarchar(10) )
' CON FECHA DE: ' (GETDATE())
' CON LA DURACION DE: '
CAST(DURACION AS nvarchar(5))
'Y EL CODIGO DE: '
(SELECT CODIGO FROM INSERTED)
' POR EL USUARIO: '
CAST((CURRENT_USER) AS CHAR)
);
Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что он не распознает DURACION и COSTO как допустимые столбцы.
Вот моя структура таблицы для CURSO.
CREATE TABLE CURSO(
CODIGO CHAR(5) NOT NULL,
NOMBRE CHAR(40) NOT NULL,
COSTO INT NOT NULL,
FECHA_INI DATE NOT NULL,
DURACION INT NOT NULL,
RFC_I CHAR(13) NULL
);
CREATE TABLE TOTALES(
TOTAL_INSTRUCTORES INT NULL,
TOTAL_CURSOS INT NULL,
TOTAL_ESTUDIANTES INT NULL
);
CREATE TABLE BITACORA(
MOMENTO CHAR(30) NOT NULL,
DESCRIPCION CHAR(150) NOT NULL
);
Комментарии:
1. Ваши структуры таблиц? Пожалуйста, опубликуйте свои структуры таблиц, чтобы многие разработчики могли помочь вам с этой проблемой.
2. Откуда они должны взяться? Вы в основном выполняете вставку с этими столбцами, не указывая, откуда они. Вы хотите извлечь их из INSERTED, как и другие столбцы?
3. Да, я попытался выполнить следующее, ВСТАВИЛ.COSTO, но я получаю сообщение об ошибке, что оно не может быть привязано.
4. Вместо использования a
TRIGGER
, почему бы вместо этого не использовать индексированное представление? Триггеры не так надежны, как индексированные представления, которые имеют привязку к схеме.5. В данном конкретном случае я должен использовать триггер.
Ответ №1:
Попробуйте более простые инструкции и проверьте, что они работают должным образом, затем соберите их в более сложные последовательности. Не пытайтесь оптимизировать, пока у вас не будет рабочего решения.
Например, попробуйте это, измените эти :
CAST(COSTO AS nvarchar(10) )
' CON FECHA DE: ' (GETDATE())
' CON LA DURACION DE: '
CAST(DURACION AS nvarchar(5))
Для:
CAST((SELECT COSTO FROM INSERTED.CURSO) AS nvarchar(10) )
' CON FECHA DE: ' (GETDATE())
' CON LA DURACION DE: '
CAST((SELECT DURACION FROM INSERTED.CURSO) AS nvarchar(5))
Это может сработать или нет. Идея состоит в том, чтобы найти то, что работает, делая небольшие шаги.
Комментарии:
1. хай @ Дай, спасибо, идея здесь в том, что op должен вместо того, чтобы пробовать сложные операторы, тестировать и взламывать простые и собирать из них сложный
2. Я просто форматировал ваш код, я не придавал никакого значения.
3. @Dai, я знаю, почему thx, и мой комментарий просто для того, чтобы побудить op попробовать что-то, если намерение неясно из краткости ответа
Ответ №2:
Вы можете изменить вставку из значений на вставку из select.
CREATE TRIGGER [TR_CURSO] ON [CURSO]
AFTER INSERT
AS
BEGIN
UPDATE
TOTALES
SET
TOTAL_CURSOS = ( SELECT COUNT(CODIGO) FROM CURSO );
INSERT INTO BITACORA (
MOMENTO,
DESCRIPCION
)
SELECT
SYSDATETIME() AS MOMENTO,
CONCAT (
'SE INSERTO EL MAESTRO CON RFC DE: ', RTRIM(RFC_I),
' DEL CURSO: ', RTRIM(NOMBRE),
' CON COSTO DE: ', COSTO,
' CON FECHA DE: ', GETDATE(),
' CON LA DURACION DE: ', DURACION,
'Y EL CODIGO DE: ', RTRIM(CODIGO),
' POR EL USUARIO: ', CURRENT_USER
) AS DESCRIPCION
FROM INSERTED;
END;
Демонстрация в db<>fiddle здесь
Комментарии:
1. Триггер всегда должен проверять, действительно ли были вставлены строки, прежде чем что-либо делать. Вставка нулевых строк все равно приведет к выполнению триггера, который затем обновит первую таблицу (вызывая выполнение триггера обновления, если он определен), а затем вставит нулевые строки во вторую таблицу (вызывая выполнение триггера вставки, если он определен) и так далее.
2. @SMor Триггер after insert не запускается при сбое вставки. Смотрите демонстрацию.