将select查询中的值插入变量

时间:2015-11-12 15:46:23

标签: sql oracle plsql

我试图从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数据。这就是为什么唱片有时会成倍增加的原因。

当程序逐个处理每个记录然后将其作为发散

2 个答案:

答案 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”部分