'PLS-00103在尝试连接触发器中的某些字符串时遇到符号“+”...'错误

时间:2015-06-18 15:36:34

标签: sql triggers oracle-sqldeveloper

我有一个SQL表,其中特定record ID(主键)可能有多个Contact ID s。我想创建一个触发器,每次添加新行时,它都会检查record ID是否存在,如果存在,则会将新Contact ID添加到当前Contact ID字段用逗号分隔(基本上创建一个列表)。因此,对于多个Contact ID,该字段可能变为:

Contact123, Contact456, Contact999

为此,我写了以下触发器:

CREATE OR REPLACE
TRIGGER "TEST_INSERT" BEFORE
   INSERT ON "TEST_INSERT" REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW DECLARE REC_COUNT INTEGER;
BEGIN
   SELECT COUNT(*)
   INTO REC_COUNT
   FROM TEST_INSERT
   WHERE RECORDID = :NEW.RECORDID;
   IF REC_COUNT > 0 THEN
      CONTACTID + ', ' + :NEW.CONTACTID AS CONTACTID;   --This is the line where I'm getting the error
   END IF;
END;

我收到了+符号以及AS操作的错误消息。我完全错误地采取了这种方式吗?

由于

2 个答案:

答案 0 :(得分:1)

您无法将插入内容更改为触发器中的更新。无论如何,您的错误行中存在几个问题:

$con = mysql_connect("192.155.247.248:3307","uqDqUZ2EKoZ5I","pWXeBZbNtdpOv"); 
if (!$con){ 
    echo "Failed to connect to MySQL: " .mysql_error(); 
} 
mysql_select_db("d65a2b7e14b594d18a049ac918a4a8603",$con);

除了使用+而不是||对于连接,您没有将新值分配给变量 - CONTACTID + ', ' + :NEW.CONTACTID AS CONTACTID; 并不存在于您正在使用的PL / SQL范围内,尽管您可能会将该连接作为一部分进行连接。更新(也没有CONACTID子句),你不能在插入前插入每行插入触发器中进行更新,因为你遇到了变异表错误,即使插入工作仍然会发生。

看起来你真的想做一个“吵架”。 - 更新现有记录(如果存在),或者添加新记录(如果不存在)。在Oracle中,您使用the merge statement执行此操作。这是一个例子,我把它包含在一个过程中只是为了使调用更清晰并减少重复 - 它通常只是简单的SQL而不是嵌入在PL / SQL中:

AS

但是存储以逗号分隔的非规范化数据列表并不是一个好主意。您需要考虑如何修改该值(如果您必须删除联系人,比如说,或者希望它们被订购)以及如何使用字符串中的值 - 假设每个联系人ID都是对另一个的引用表你必须解构字符串才能进行连接。您还受限但是字符串列的最大大小。

最好有一个单独的表链接记录和联系人ID:

create table test_merge (recordid number primary key,
  contactid varchar2(4000));

create procedure p_merge(p_recordid number, p_contactid number) as
begin
  merge into test_merge t
  using (select p_recordid as recordid, p_contactid as contactid from dual) x
  on (t.recordid = x.recordid)
  when matched then
    update set contactid = t.contactid ||','|| x.contactid
  when not matched then
    insert (recordid, contactid) values (x.recordid, x.contactid);
end;
/

exec p_merge (1, 123);
exec p_merge (1, 234);
exec p_merge (1, 456);
exec p_merge (2, 567);

select * from test_merge;

  RECORDID CONTACTID          
---------- --------------------
         1 123,234,456         
         2 567                 

如果要查看以逗号分隔的列表,请在需要时使用字符串聚合生成该列表。 11g及以上有the built-in listagg function来执行此操作:

create table test_parent (recordid number primary key);
create table test_child (recordid number references test_parent(recordid),
  contactid number);

insert into test_parent (recordid) values (1);
insert into test_parent (recordid) values (2);
insert into test_child (recordid, contactid) values (1, 123);
insert into test_child (recordid, contactid) values (1, 234);
insert into test_child (recordid, contactid) values (1, 456);
insert into test_child (recordid, contactid) values (2, 567);

答案 1 :(得分:0)

在SQL Server和Microsoft Access中,您使用+连接,但在oracle中使用||连接在mySQL中你使用CONCAT函数。你确定在你的情况下你正在使用正确的连接(如果我没记错PLS意味着它是一个oracle错误,所以你应该使用||而不是+)?