2016-09-28 1 views
2

PostgreSQL (v 9) db에 트리거를 추가하려고하는데이 목표를 달성하기 위해 레일즈 마이그레이션 (v 4.2.7 사용)을 만들고 싶습니다. 작업, 나는 다음과 같은 오류 실행하기 위해Rails 마이그레이션에서 트리거를 작성하려면 어떻게해야합니까?

davea$ rake db:migrate 
== 20160928184431 CreateDeleteAddressTriggers: migrating ====================== 
-- execute("  CREATE OR REPLACE FUNCTION remove_address() RETURNS trigger\n  LANGUAGE plpgsql AS\n  $$BEGIN\n   DELETE FROM public.addresses WHERE id = OLD.address_id;\n  END;$$;\n\n  CREATE TRIGGER remove_my_object_address\n  AFTER DELETE ON public.my_objects FOR EACH ROW\n  EXECUTE TRIGGER remove_address()\n\n  CREATE TRIGGER remove_user_address\n  AFTER DELETE ON public.users FOR EACH ROW\n  EXECUTE TRIGGER remove_address()\n") 
rake aborted! 
StandardError: An error has occurred, this and all later migrations canceled: 

PG::SyntaxError: ERROR: syntax error at or near "TRIGGER" 
LINE 9:   EXECUTE TRIGGER remove_address() 
         ^
:  CREATE OR REPLACE FUNCTION remove_address() RETURNS trigger 
     LANGUAGE plpgsql AS 
     $$BEGIN 
      DELETE FROM public.addresses WHERE id = OLD.address_id; 
     END;$$; 

     CREATE TRIGGER remove_my_object_address 
     AFTER DELETE ON public.my_objects FOR EACH ROW 
     EXECUTE TRIGGER remove_address() 

     CREATE TRIGGER remove_user_address 
     AFTER DELETE ON public.users FOR EACH ROW 
     EXECUTE TRIGGER remove_address() 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `block in execute' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract_adapter.rb:484:in `block in log' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activesupport-4.2.7.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract_adapter.rb:478:in `log' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:154:in `execute' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/migration.rb:665:in `block in method_missing' 
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/migration.rb:634:in `block in say_with_time' 

가 어떻게 내 마이그레이션을 수정할 수 있습니다를 얻을 : 그래서 내가 "마이그레이션 레이크 DB"를 실행할 때

class CreateDeleteAddressTriggers < ActiveRecord::Migration 
    def change 
    execute <<-SQL 
     CREATE OR REPLACE FUNCTION remove_address() RETURNS trigger 
     LANGUAGE plpgsql AS 
     $$BEGIN 
      DELETE FROM public.addresses WHERE id = OLD.address_id; 
     END;$$; 

     CREATE TRIGGER remove_my_object_address 
     AFTER DELETE ON public.my_objects FOR EACH ROW 
     EXECUTE TRIGGER remove_address() 

     CREATE TRIGGER remove_user_address 
     AFTER DELETE ON public.users FOR EACH ROW 
     EXECUTE TRIGGER remove_address() 
    SQL 
    end 
end 

불행하게도이 콘텐츠와 마이그레이션을 생성 제대로 작동합니까?

편집 : 주어진 대답에 대응하여, 이것은 당신은 당신의 SQL에 잘못된 구문을 사용하고 발생하는 오류 ...

ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "CREATE" 
LINE 11:  CREATE TRIGGER remove_user_address 

답변

5

했다. 너 EXECUTE PROCEDURE이 아니라 EXECUTE TRIGGER이 필요합니다. The PostgreSQL docs :

당신은

CREATE TRIGGER remove_my_object_address 
    AFTER DELETE ON public.my_objects FOR EACH ROW 
    EXECUTE PROCEDURE remove_address() 
      ^^^^^^^^^ 

CREATE TRIGGER remove_user_address 
    AFTER DELETE ON public.users FOR EACH ROW 
    EXECUTE PROCEDURE remove_address() 
      ^^^^^^^^^ 

소스가 있어야합니다.

+0

"EXECUTE TRIGGER"를 "EXECUTE PROCEDURE"로 바꾸었지만 "PG :: SyntaxError : ERROR : CREATE"또는 근처에서 구문 오류가 발생했습니다. LINE 11 : CREATE TRIGGER remove_user_address " – Dave

+0

@Dave 각 문장 다음에 세미콜론이 필요합니다. – meagar

+0

@meagar 함수 및 트리거 마이그레이션을 처리하는이 방법은 test env migration에서 코드를 실행하지 않습니다. 어떤 제안? – carbonr

관련 문제