5
respostas

Trigger

Estou desenvolvendo um projeto e implementei uma trigger que quando o usuario deletar um ou mais registros do banco ele salva esses dados apagados em outra tabela, em teoria e particamente está funcionando, só que quando eu vou deletar varios registros de uma vez só, ele salva so um vez. Como sou iniciante em sql, ainda naõ consegui me aprofundar tanto em triggers.

CREATE TRIGGER deleteRegistro
ON [dbo].[registroMaquina]
FOR DELETE
AS
BEGIN

    DECLARE
    @idRegistro INT,
    @registroHora DATETIME,
    @usoRam DECIMAL(10,2),
    @usoCPU INT,
    @frequenciaCPU DECIMAL(10,2),
    @usoDisco DECIMAL(10,2),
    @fkMaquina INT

    SELECT @idRegistro = idRegistro, @registroHora = dataHora, @usoRam = usoRam, 
    @frequenciaCPU = frequenciaCPU, @usoDisco = usoDisco, @fkMaquina = fkMaquina 
    FROM DELETED

    INSERT INTO [dbo].[registroDelete] (horaDelete, idRegistro, registroHora, 
    usoRam, usoCPU, frequenciaCPU, usoDisco, fkMaquina) VALUES (CURRENT_TIMESTAMP, 
    @idRegistro, @registroHora, @usoRam, @usoCPU, @frequenciaCPU, 
    @usoDisco, @fkMaquina)

END
5 respostas

Opa, boa noite, acredito que o comando que pode te ajudar seria o FOR EACH ROW. Fiz um exemplo bem básico utilizando este comando, espero que ajude:

USE dbo;

CREATE TABLE teste (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    teste VARCHAR(30) NOT NULL
);

CREATE TABLE testeHistory (
    id INT UNSIGNED,
    teste VARCHAR(30) NOT NULL
);

CREATE TRIGGER deleteTeste
AFTER DELETE ON teste 
FOR EACH ROW
INSERT INTO testeHistory (id, teste)
VALUES (old.id, old.teste);

INSERT INTO teste (teste)
VALUES ('teste 1'),
       ('teste 2'),
       ('teste 3');

SELECT * FROM teste;
DELETE FROM teste;
SELECT * FROM testeHistory;

Link sobre: https://www.mysqltutorial.org/mysql-triggers/mysql-after-delete-trigger/

Estou desenvolvendo essa logica no sql acredito que não seja a mesma sintaxe do que a do mysql... Teria alguma opção pro sql?

Opa, a sintaxe é bem semelhante, segue um exemplo que encontrei no site da Oracle.

https://docs.oracle.com/cd/B10500_01/appdev.920/a96590/adg13trg.htm#:~:text=value%20of%2010.-,Firing%20Triggers%20One%20or%20Many%20Times%20(FOR%20EACH%20ROW%20Option,For%20example%2C%20you%20define%20the%20following%20trigger%3A,-Note%3A

Aqui outro exemplo de Triggers em SQL com FOR EACH ROW https://www.alura.com.br/artigos/trigger-em-sql#:~:text=Exemplo%20de%20Triggers,trigger.%0AEND%20//%0Adelimiter%20%3B

Desculpe dei uma pesquisada e o sql servernao fornece o gatilho FOR EACH ROW, assim como exemplos que você encaminhou em seus links só exemplifica dentro de topicos como mysql e oracle, mas sem problemas, obrigado Insira aqui a descrição dessa imagem para ajudar na acessibilidadeEu pesquisei algumas soluções viaveis e encontrei o CURSOR FOR, porém agora ele não deixa ne eu deletar minha tabela, vou encaminhar o codigo para verificar o erro que estou cometendo, pois não consegui identificar.

CREATE TRIGGER deleteRegistro
ON registroMaquina
FOR DELETE
AS
BEGIN
    DECLARE
    @idRegistro INT,
    @dataHora DATETIME,
    @usoRam DECIMAL(10,2),
    @usoCPU INT,
    @frequenciaCPU DECIMAL(10,2),
    @usoDisco DECIMAL(10,2),
    @fkMaquina INT

    DECLARE CursorSelect CURSOR FOR

    SELECT idRegistro, dataHora, usoRam, usoCpu 
    frequenciaCPU, usoDisco, fkMaquina 
    FROM DELETED

    OPEN CursorSelect

    FETCH NEXT FROM CursorSelect INTO @idRegistro, @dataHora, @usoRam, @usoCPU, @frequenciaCPU, @usoDisco, @fkMaquina

    WHILE @@FETCH_STATUS = 0

    BEGIN
        INSERT INTO registroDelete (horaDelete, idRegistro, registroHora, 
        usoRam, usoCPU, frequenciaCPU, usoDisco, fkMaquina) VALUES (CURRENT_TIMESTAMP, 
        @idRegistro, @dataHora, @usoRam, @usoCPU, @frequenciaCPU, 
        @usoDisco, @fkMaquina)
    END

END

E O ERRO DO TERMINAL É O SEGUINTE... Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Consegui a resolução do meu problema, ObrigadoGabriel

CREATE TRIGGER deleteRegistro
ON registroMaquina
FOR DELETE
AS
BEGIN
    DECLARE
    @idRegistro INT,
    @dataHora DATETIME,
    @usoRam DECIMAL(10,2),
    @usoCPU INT,
    @frequenciaCPU DECIMAL(10,2),
    @usoDisco DECIMAL(10,2),
    @fkMaquina INT

    DECLARE CursorSelect CURSOR FOR

    SELECT idRegistro, dataHora, usoRam, usoCpu,
    frequenciaCPU, usoDisco, fkMaquina
    FROM DELETED

    OPEN CursorSelect

    FETCH NEXT FROM CursorSelect INTO @idRegistro, @dataHora, @usoRam, @usoCPU, @frequenciaCPU, @usoDisco, @fkMaquina

    WHILE @@FETCH_STATUS = 0

    BEGIN
        INSERT INTO registroDelete (horaDelete, idRegistro, registroHora,
        usoRam, usoCPU, frequenciaCPU, usoDisco, fkMaquina) VALUES (CURRENT_TIMESTAMP,
        @idRegistro, @dataHora, @usoRam, @usoCPU, @frequenciaCPU,
        @usoDisco, @fkMaquina)

        -- para que o cursor vá para o proximo registro
        FETCH NEXT FROM CursorSelect INTO @idRegistro, @dataHora, @usoRam, @usoCPU, @frequenciaCPU, @usoDisco, @fkMaquina
    END
    --desaloca o cursor da memória ;)
    CLOSE CursorSelect
    DEALLOCATE CursorSelect
END