Alguns problemas em nenhuma ordem específica.
Primeiro, no corpo de um gatilho em nível de linha, você precisa usar
:new
e :old
para referenciar os registros novos e antigos. Os dois pontos principais são necessários. Portanto, seu WHERE
cláusula precisaria ser WHERE PROJECTID = :new.PROJECTID
Segundo, se você estiver executando seu
CREATE TRIGGER
no SQL*Plus, você pode obter uma lista dos erros e avisos usando o SHOW ERRORS
comando, ou seja SQL> show errors
Você também pode consultar o
DBA_ERRORS
tabela (ou ALL_ERRORS
ou USER_ERRORS
dependendo do seu nível de privilégio), mas isso não é algo que você normalmente precisa recorrer. Terceiro, supondo que os erros de sintaxe sejam corrigidos, você obterá uma mutating erro de tabela se você usar essa lógica. Um gatilho de nível de linha na tabela A (
TPM_TRAININGPLAN
neste caso) não pode consultar a tabela A porque a tabela pode estar em um estado inconsistente. Você pode contornar isso, como Tim mostra em seu artigo, criando um pacote com uma coleção, inicializando essa coleção em um gatilho de instrução antes, preenchendo os dados da coleção em um gatilho de nível de linha e processando as linhas modificadas em um gatilho de instrução after. Essa é uma quantidade razoável de complexidade para adicionar ao sistema, no entanto, já que você terá que gerenciar vários objetos diferentes. Geralmente, seria melhor implementar essa lógica como parte de qualquer API que você usa para manipular o
TPM_TRAININGPLAN
tabela. Se for um procedimento armazenado, faz muito mais sentido colocar a lógica para atualizar TPM_PROJECT
nesse procedimento armazenado em vez de colocá-lo em um gatilho. É notoriamente doloroso tentar depurar um aplicativo que tem muita lógica embutida em gatilhos porque isso torna muito difícil para os desenvolvedores seguirem exatamente quais operações estão sendo executadas. Como alternativa, você pode remover o TRAININGDELIVERYSTART
coluna de TPM_PROJECT
tabela e apenas calcular a data de início mínima em tempo de execução. Quarto, se o seu acionador for acionado em inserções, atualizações e exclusões, você não poderá simplesmente referenciar
:new
valores. :new
é válido para inserções e atualizações, mas será NULL se você estiver fazendo uma exclusão. :old
é válido para exclusões e atualizações, mas será NULL se você estiver fazendo uma inserção. Isso significa que você provavelmente precisa ter lógica ao longo das linhas de (referenciando a solução de pacote de Tim) BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;