ORA-00927:从触发器中丢失等号和错误的绑定变量错误

时间:2017-06-12 11:03:38

标签: oracle plsql database-trigger

我遇到了这个触发器的问题,我不明白为什么它不起作用。我的数据库中有两个表,我想在修改表“mensajes”时创建一个触发器来更新表“mensajes_info”

CREATE TABLE ESC.MENSAJES (CODIGO NUMBER(20) PRIMARY KEY,
  TEXTO VARCHAR2(200),
  TIPO VARCHAR2(30)) ;

CREATE TABLE MENSAJES_INFO ( TIPO VARCHAR2(30) NOT NULL,
  CUANTOS_MENSAJES NUMBER(2),
  ULTIMO VARCHAR2(200),
  CONSTRAINT MENSAJES_INFO_PK PRIMARY KEY (TIPO ) ENABLE );

create or replace TRIGGER ACTUALIZA_TB_MENS_INFO 
AFTER DELETE OR INSERT OR UPDATE ON ESC.MENSAJES 
FOR EACH ROW
BEGIN
  IF INSERTING THEN
    UPDATE MENSAJES_INFO SET(ULTIMO) SELECT :NEW.TEXT0 FROM ESC.MENSAJES;
  ELSIF DELETING THEN
    UPDATE MENSAJES_INFO SET(CUANTOS_MENSAJES, ULTIMO)
    ((CUANTOS_MENSAJES)-1, NULL) WHERE :OLD.tipo = tipo;
  ELSIF UPDATING THEN
    IF(:OLD.tipo != :NEW.tipo) THEN
      UPDATE  MENSAJES_INFO SET(CUANTOS_MENSAJES, ULTIMO)         
      (select(CUANTOS_MENSAJES)-1, NULL)  WHERE :OLD.tipo != :NEW.tipo;
    ELSE
      UPDATE MENSAJES_INFO SET (CUANTOS_MENSAJES, ULTIMO)
      VALUES(select(CUANTOS_MENSAJES)+1, :NEW.TEXT0) WHERE :new.tipo = tipo ;
    END IF;
  END IF;
END;

我收到编译错误:

TRIGGER的错误MY_SCHEMA.ACTUALIZA_TB_MENS_INFO:

LINE/COL ERROR
-------- ------------------------------------------------------
3/5      PL/SQL: SQL Statement ignored
3/38     PL/SQL: ORA-00927: missing equal sign
3/45     PLS-00049: bad bind variable 'NEW.TEXT0'
5/5      PL/SQL: SQL Statement ignored
6/5      PL/SQL: ORA-00927: missing equal sign
9/7      PL/SQL: SQL Statement ignored
10/7     PL/SQL: ORA-00927: missing equal sign
12/7     PL/SQL: SQL Statement ignored
13/7     PL/SQL: ORA-00927: missing equal sign
13/42    PLS-00049: bad bind variable 'NEW.TEXT0'

我做错了什么?

2 个答案:

答案 0 :(得分:1)

您的代码中有几个问题。最紧迫的是,您的更新语句格式不正确,如 from django.db import models from django.conf import settings from django.db.models.signals import post_save # Create your models here. class Question(models.Model): text = models.TextField() active = models.BooleanField(default = True) draft = models.BooleanField(default = False) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) #answers = models.ManyToManyField('Answer') def __unicode__(self): return self.text[:10] class Answer(models.Model): question = models.ForeignKey(Question) text = models.CharField(max_length=120) active = models.BooleanField(default=True) draft = models.BooleanField(default=False) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) def __unicode__(self): #def __str__(self): return self.text[:10] LEVELS = ( ('Mandatory', 'Mandatory'), ('Very Important', 'Very Important'), ('Somewhat Important', 'Somewhat Important'), ('Not Important', 'Not Important'), ) class UserAnswer(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL) question = models.ForeignKey(Question) my_answer = models.ForeignKey(Answer, related_name = 'user_answer') my_answer_importance = models.CharField(max_length=50, choices= LEVELS) my_points = models.IntegerField(default=-1) their_answer = models.ForeignKey(Answer, null=True, blank=True, related_name = 'match_answer') their_importance = models.CharField(max_length=50, choices= LEVELS) their_points = models.IntegerField(default=-1) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) def __unicode__(self): return self.my_answer.text[:10] def score_importance(importance_level): if importance_level == "Mandatory": points = 300 elif importance_level == "Very Important": points = 200 elif importance_level == "Somewhat Important": points = 50 elif importance_level == "Not Important": points = 0 else: points = 0 return points def update_user_answer_score(sender, instance, created, *args, **kwargs): #print sender print instance #print created if instance.my_points == -1: my_points = score_importance(instance.my_answer_importance) instance.my_points = my_points print my_points instance.save() if instance.their_points == -1: their_points = score_importance(instance.their_importance) instance.their_points = their_points print my_points instance.save() post_save.connect(update_user_answer_score, sender=UserAnswer) 消息所示。

ORA-00927: missing equal sign

无效;首先,你需要一个等号作为the update-set clause的一部分;其次,你没有从原始表中选择新的/旧的伪记录值,你只需直接引用UPDATE MENSAJES_INFO SET(ULTIMO) SELECT :NEW.TEXT0 FROM ESC.MENSAJES; :第三,你的表定义说列名是:new.<column>而不是texto

text0

同样在第二次更新中,您错过了一个等号,并且您只能在子括号中使用子查询设置多个值:

UPDATE MENSAJES_INFO SET ULTIMO = :NEW.TEXTO;

您的第三次和第四次更新可能是为了更新两种类型的消息计数,并且有类似的其他问题;第三个也是goign更新表中的所有行,这不是你想要的,所以你可能想要这样的东西:

UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES - 1, ULTIMO = NULL

所以,更像是:

IF(:OLD.tipo != :NEW.tipo) THEN
  UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES - 1, ULTIMO = NULL
  WHERE :OLD.tipo = tipo;
END IF;
UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES + 1, UNLTIMO = :NEW.TEXT0
WHERE :NEW.tipo = tipo;

我还删除了不必要的括号。详细了解the update statementtriggerspseudorecords

尝试通过触发器维护计数和其他聚合信息会让您感到头疼,因为针对CREATE OR REPLACE TRIGGER ACTUALIZA_TB_MENS_INFO AFTER DELETE OR INSERT OR UPDATE ON MENSAJES FOR EACH ROW BEGIN IF INSERTING THEN UPDATE MENSAJES_INFO SET ULTIMO = :NEW.TEXTO; ELSIF DELETING THEN UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES - 1, ULTIMO = NULL WHERE :OLD.tipo = tipo; ELSIF UPDATING THEN IF(:OLD.tipo != :NEW.tipo) THEN UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES - 1, ULTIMO = NULL WHERE :OLD.tipo = tipo; END IF; UPDATE MENSAJES_INFO SET CUANTOS_MENSAJES = CUANTOS_MENSAJES + 1, ULTIMO = :NEW.TEXTO WHERE :NEW.tipo = tipo; END IF; END; / 的同时操作可能会使MENSAJES表处于您不期望的状态,除非访问权限是序列化。对于计数,基表的视图会更简单:

MENSAJES_INFO

...但这对CREATE VIEW MENSAJES_INFO AS SELECT TIPO, COUNT(*) AS CUANTOS_MENSAJES FROM MENSAJES GROUP BY TIPO; ...

没有帮助

答案 1 :(得分:1)

我怀疑在单独的表中存储每种类型的消息数是个好主意,您总是可以选择这样的数据。但如果你坚持请尝试这样的事情:

create or replace trigger actualiza_tb_mens_info
  after delete or insert or update on mensajes
  for each row

begin
  if inserting then

    merge into mensajes_info mi
    using (select :new.tipo tipo, :new.texto texto from dual) m
    on (mi.tipo = m.tipo)
    when matched then update set
      cuantos_mensajes = cuantos_mensajes + 1, ultimo = m.texto
    when not matched then
      insert (tipo, cuantos_mensajes, ultimo) values (m.tipo, 1, m.texto);

  elsif deleting then

    update mensajes_info set
        cuantos_mensajes = cuantos_mensajes - 1, ultimo = null
      where tipo = :old.tipo;

  elsif updating then
    if :old.tipo != :new.tipo then

      update mensajes_info set
          cuantos_mensajes = cuantos_mensajes - 1, ultimo = null
        where tipo = :old.tipo;

      merge into mensajes_info mi
      using (select :new.tipo tipo, :new.texto texto from dual) m
      on (mi.tipo = m.tipo)
      when matched then update set
        cuantos_mensajes = cuantos_mensajes + 1, ultimo = m.texto
      when not matched then
        insert (tipo, cuantos_mensajes, ultimo) values (m.tipo, 1, m.texto);

    else

      update mensajes_info set ultimo = :new.texto 
        where tipo = :new.tipo;

    end if;
  end if;
end;

在插入使用merge语句时,删除正确的update时,更新时 - 取决于邮件类型是否发生变化。

测试:

insert into mensajes (codigo, texto, tipo) values (1, 'Text 1', 'Type 1');
insert into mensajes (codigo, texto, tipo) values (2, 'Text 11', 'Type 1');  
insert into mensajes (codigo, texto, tipo) values (3, 'Text 12', 'Type 1');
insert into mensajes (codigo, texto, tipo) values (4, 'Text 21', 'Type 2');

delete from mensajes where codigo = 2;

update mensajes set tipo = 'Type 2' where codigo = 3;

select * from mensajes_info;

TIPO    CUANTOS_MENSAJES  ULTIMO
------  ----------------  --------------------
Type 1                 1  
Type 2                 2  Text 12