我有一个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
操作的错误消息。我完全错误地采取了这种方式吗?
由于
答案 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错误,所以你应该使用||而不是+)?