Oracle11g 中“插入所有”RDF 三元组引发的异常

Exception thrown by `Insert all` RDF triples in Oracle11g

创建包含 rdf 数据的新 table 之后

create table rdf_data (triple SDO_RDF_TRIPLE_S);
execute SEM_APIS.CREATE_SEM_MODEL('mymodel', 'rdf_data', 'triple');

我正在尝试一次添加多个 RDF 三元组

insert all 
into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', 'foo', 'bar', 'foobar'))
into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', 'bar', 'foo', 'foobar')) 
select 1 from dual;

但是,我收到以下错误:

ORA-00932:  inconsistent datatypes: expected NUMBER got BINARY
00932. 00000 -  "inconsistent datatypes: expected %s got %s"

相反,以下示例有效:

-- Trying insert all with integers
create table foo(a integer);
insert all 
into foo values (1) 
into foo values (2) 
select 1 from dual;

-- Inserting a single RDF triple
insert into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', 'foo', 'bar', 'foobar'));

但是,给定一个包含 1,000,000 个元组的 table,我需要为每个元组执行多次插入(例如,为每个 table 属性执行一次插入)。我想多次插入不是一个可行的解决方案。

create table bar(id varchar(100), foo char(100), foobar char(100));
insert all
into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<rdfs:type>', '<myont:Bar>'))
into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFoo>', foo))
into rdf_data(triple) 
values (sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFooBar>', foobar)) 
into rdf_data(triple) values (...)
select * from bar;

使用 insert all 插入多个三元组时是否存在任何已知错误?

我想你可以说这是一个错误。或者至少在处理 SDO_TRIPLE_S 对象类型时存在限制 ...

那么,为什么不使用多个插入呢?

编辑 1:基于 OP 的说明。

所以实际需要是从单个输入行生成多个三元组。很抱歉从原始问题中遗漏了这一点。这绝对是多插入语句的合适用途。不幸的是,当值列表包含 SDO_RDF_TRIPLE_S 对象时,这似乎不起作用。该限制不适用于所有对象(其他对象类型可以正常工作)。

但是 SDO_RDF_TRIPLE_S 构造函数在检查物理三元组存储中是否存在现有值方面做了大量工作。我想这就是造成麻烦的原因......

编辑 2:原始的 INSERT ALL 语法可以正常工作 只要您插入的列多于三元组本身。

让我们像这样重新定义三元组 table:

create table rdf_data (id number,triple SDO_RDF_TRIPLE_S);

并在插入中填写新的 ID 列,如下所示:

insert all
into rdf_data(id, triple) 
values (id, sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<rdfs:type>', '<myont:Bar>'))
into rdf_data(id, triple) 
values (id, sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFoo>', foo))
into rdf_data(id, triple) 
values (id, sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFooBar>', foobar)) 
select * from bar;

12 rows created.

Elapsed: 00:00:00.10

该操作成功完成。我不知道为什么只插入三重对象时多插入失败。我们需要对此进行调查。

编辑 3:解决方法:使用多个插入

另一种解决方法是使用多个连续的 INSERT ... SELECT,每个都生成一种要从输入行中生成的三元组。

考虑这是输入 table 三元组的来源:

create table bar(id varchar(100), foo char(100), foobar char(100));
insert into bar (id, foo, foobar) values (1, 'F1', 'FB1');
insert into bar (id, foo, foobar) values (2, 'F2', 'FB2');
insert into bar (id, foo, foobar) values (3, 'F3', 'FB3');
insert into bar (id, foo, foobar) values (4, 'F4', 'FB4');
commit;

插入内容如下:

-- Insert the "<rdfs:type>" triples
insert into rdf_data(triple) 
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<rdfs:type>', '<myont:Bar>')
from bar;

-- Insert the "<myont:hasFoo>" triples
insert into rdf_data(triple) 
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFoo>', foo)
from bar;

-- Insert the "<myont:hasFooBar>" triples
insert into rdf_data(triple) 
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFooBar>', foobar)
from bar;

commit;

变体可以更有效:

insert /*+ append */ into rdf_data(triple) 
-- Insert the "<rdfs:type>" triples
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<rdfs:type>', '<myont:Bar>')
from bar
union all
-- Insert the "<myont:hasFoo>" triples
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFoo>', foo)
from bar
union all
-- Insert the "<myont:hasFooBar>" triples
select sdo_rdf_triple_s('mymodel', '<myont:'||id||'>', '<myont:hasFooBar>', foobar)
from bar;
commit;