我试图从select语句中插入2个变量值,但是我收到一条错误,上面写着:
精确提取返回超过请求的行数
我猜我需要将select数据中的数据放入某些表类型中吗? 但我需要处理单个记录,以便与变量v_zmienna和v_zmienna2进行比较。
正如你所看到的,我尝试以某种方式将数据传输到v_zmienna和v_zmienna2,然后比较这些值。
有人可以看看并提出最好的方法吗?
我需要使用execute immediate和variables,因为我有Table1,Table2表作为配置表,其中包含应该连接的表的名称等。
declare
c1 SYS_REFCURSOR;
v_sourcepkcolumn varchar2(50);
v_sourcetable varchar2(50);
v_targetfkcolumn varchar2(50);
v_targetpkcolumn varchar2(50);
v_targettable varchar2(50);
v_sourcecolumn varchar2(50);
v_targetcolumn varchar2(50);
v_verificationdefid varchar2(50);
v_zmienna varchar2(50);
v_zmienna2 varchar2(50);
v_random_number number;
begin
v_random_number := sequence1.nextval;
open c1 for select sourcepkcolumn,
sourcetable,
targetfkcolumn,
targetpkcolumn,
targettable,
sourcecolumn,
targetcolumn,
ID
from table1,table2 where table1.ID=table2.ID;
loop
fetch c1 into v_sourcepkcolumn,
v_sourcetable,
v_targetfkcolumn,
v_targetpkcolumn,
v_targettable,
v_sourcecolumn,
v_targetcolumn,
v_verificationdefid;
exit when c1%notfound;
execute immediate 'select '||v_sourcetable||'.'||v_sourcecolumn||','||v_targettable||'.'||v_targetcolumn||' from '||v_sourcetable||','||v_targettable||' where '||
v_sourcetable||'.'||v_sourcepkcolumn||'='||v_targettable||'.'||v_targetfkcolumn into v_zmienna,v_zmienna2;
if (v_zmienna=v_zmienna2) then
execute immediate 'insert into table3 values ('||v_random_number||','||v_sourcecolumn||','||v_sourcepkcolumn||','||v_zmienna||',1,'||v_targetcolumn||','||v_targetpkcolumn||','||v_zmienna2||',timestamp,'||v_verificationdefid||')';
else
execute immediate 'insert into table3 values ('||v_random_number||','||v_sourcepkcolumn||','||v_zmienna||',0,'||v_targetcolumn||','||v_targetpkcolumn||','||v_zmienna2||',timestamp,'||v_verificationdefid||')';
end if;
end loop;
close c1;
end;
编辑:
的输出
select sourcepkcolumn,
sourcetable,
targetfkcolumn,
targetpkcolumn,
targettable,
sourcecolumn,
targetcolumn,
from table1,table2 where table1.id=table2.id
可以看起来:
PK_ACCOUNT,ACCOUNT,PK_ACC,ID,ACCOUNT2,NAME,NAME
这是table1和table2的输出,
重要提示:帐户和帐户2可见!这不是表格。
所以现在我不想将帐户VIEW中的account.name和account2.name与account.pk_account = account2.pk_acc上的account2 VIEW进行比较。 一般来说,它可以完美地工作,但有时(取决于oracle顺序)在加入后的VIEW中的记录可以按其他顺序排列。 例如: 帐户:
PK_ACCOUNT NAME
1 Eva
1 Adam
和 帐户2
PK_ACCOUNT NAME
1 Adam
1 Eva
为什么在VIEW中有不同的PK_ACCOUNT?因为我需要从多个表中插入Account和Account2数据。这就是为什么唱片有时会成倍增加的原因。
当程序逐个处理每个记录然后将其作为发散
答案 0 :(得分:3)
我认为你可以把它重写为:
declare
v_random_number number;
begin
v_random_number := sequence1.nextval;
for rec in (select sourcepkcolumn,
sourcetable,
targetfkcolumn,
targetpkcolumn,
targettable,
sourcecolumn,
targetcolumn,
ID
from table1
inner join table2 on (table1.ID = table2.ID))
loop
execute immediate 'insert into table3 '||chr(10)|| -- where is the list of columns to insert into?!
' select :v_random_number random_number,'||chr(10)||
' :v_sourcecolumn source_col,'||chr(10)||
' :v_sourcepkcolumn source_pk_col,'||chr(10)||
' src.'||v_sourcecolumn||' source_col,'||chr(10)||
' case when src.'||v_sourcecolumn||' = tgt.'||v_targetcolumn||' then 1 else 0 end one_or_zero'||chr(10)||
' :v_targetcolumn target_col'||chr(10)||
' :v_targetpkcolumn target_pk_col'||chr(10)||
' tgt.'||v_targetcolumn||' target_col,'||chr(10)||
' systimestamp tstamp,'||chr(10)||
' :v_verificationdefid'||chr(10)||
' from '||v_sourcetable||' src'||chr(10)||
' inner join '||v_targettable||' tgt on (src.'||v_sourcepkcolumn||' = tgt.'||v_targetfkcolumn||')'
using v_random_number,
rec.sourcecolumn,
rec.sourcepkcolumn,
rec.targetcolumn,
rec.targetpkcolumn,
rec.id;
end loop;
end;
/
N.B。未经测试。我猜测你的第二个插入语句缺少sourcecolumn,所以我将其添加到了。
答案 1 :(得分:2)
您收到的错误表明此语句返回多行
execute immediate 'select '||v_sourcetable||'.'||v_sourcecolumn||','||v_targettable||'.'||v_targetcolumn||' from '||v_sourcetable||','||v_targettable||' where '||
v_sourcetable||'.'||v_sourcepkcolumn||'='||v_targettable||'.'||v_targetfkcolumn into v_zmienna,v_zmienna2;
根据您可能选择的目标,您有多种方法可以解决这个问题。
我推荐的方法是改变方法。您可以使用不同的方法,而不是选择一组变量,比较它们并根据变量执行不同的操作。首先,将满足动态条件的所有行插入table3。然后,将不满足动态条件的所有行插入table3。这将是这样的:
execute immediate 'insert into table3 values ('||v_random_number||','||v_sourcecolumn||','||v_sourcepkcolumn||','||v_zmienna||',1,'||v_targetcolumn||','||v_targetpkcolumn||','||v_zmienna2||',timestamp,'||v_verificationdefid||') ' ||
' select '||v_sourcetable||'.'||v_sourcecolumn||','||v_targettable||'.'||v_targetcolumn||' from '||v_sourcetable||','||v_targettable||' where '||
v_sourcetable||'.'||v_sourcepkcolumn||'='||v_targettable||'.'||v_targetfkcolumn );
execute immediate 'insert into table3 values ('||v_random_number||','||v_sourcepkcolumn||','||v_zmienna||',0,'||v_targetcolumn||','||v_targetpkcolumn||','||v_zmienna2||',timestamp,'||v_verificationdefid||' ||
' select '||v_sourcetable||'.'||v_sourcecolumn||','||v_targettable||'.'||v_targetcolumn||' from '||v_sourcetable||','||v_targettable||' where '||
v_sourcetable||'.'||v_sourcepkcolumn||'<>'||v_targettable||'.'||v_targetfkcolumn );
你的第二个选择是基本上和以前一样,但是在动态部分和固定部分上使用游标。我不会尝试为此创建源代码,但这意味着您需要为动态选择查询创建游标并在游标循环内执行“if”部分