我有两个数据表分别为:StationBaseInfo(目的表)和BS_STATION_M(源表),我想用一个存储过程将源表中的数据更新到目的表中,
  更新原则是:如果目的表中存在源表中的数据,就用源表中的数据更新目的表中的数据,如果不存在就将源表中的数据插入到目的表中。  以下是我写的存储过程,老是包错,请各位指点帮忙修改一下,谢谢: as
begin
 SET SERVERIUTPUT ON
 DECLARE 
     v_StationNo StationBaseInfo.StationNo%TYPE;  
     v_LinkPhone StationBaseInfo.LinkPhone%TYPE;
     v_IsUse StationBaseInfo.IsUse%TYPE;
     CURSOR s_cursor IS SELECT IsUse,OFFICE_TEL,ACTIVE_STATUS FROM BS_STATION_M;    
  OPEN s_cursor;  --打开游标
   LOOP  --循环游标读取数据
     FETCH s_cursor INTO v_StationNo,v_LinkPhone,v_IsUse;  
     EXIT WHEN s_cursor%NOTFOUND;   
         
      select stationno  from StationBaseInfo where stationno=v_StationNo;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN  --如果不存在,插入新数据
           insert into StationBaseInfo(StationNo,LinkPhone,IsUse)values(v_StationNo,v_LinkPhone,v_IsUse);
      update  StationBaseInfo set LinkPhone=v_LinkPhone,IsUse=v_IsUse where StationNo=v_StationNo;
   END LOOP;  
  CLOSE s_cursor;
  commit;
end;

解决方案 »

  1.   

    1、游标要放在BEGIN之前
    2、你少加个BEGIN

    select   stationno     from   StationBaseInfo   where   stationno=v_StationNo; 
                EXCEPTION 
                    WHEN   NO_DATA_FOUND   THEN     --如果不存在,插入新数据 
                          insert   into   StationBaseInfo(StationNo,LinkPhone,IsUse)values(v_StationNo,v_LinkPhone,v_IsUse); 
                update     StationBaseInfo   set   LinkPhone=v_LinkPhone,IsUse=v_IsUse   where   StationNo=v_StationNo; 
    这里要加个BEGIN END才行CURSOR   s_cursor   IS   SELECT   IsUse,OFFICE_TEL,ACTIVE_STATUS   FROM   BS_STATION_M; 
    begin 
      SET   SERVERIUTPUT   ON 
      DECLARE   
              v_StationNo   StationBaseInfo.StationNo%TYPE;     
              v_LinkPhone   StationBaseInfo.LinkPhone%TYPE; 
              v_IsUse   StationBaseInfo.IsUse%TYPE; 
              a_stationno   StationBaseInfo.StationNo%TYPE; 
                      
        OPEN   s_cursor;     --打开游标 
          LOOP     --循环游标读取数据 
              FETCH   s_cursor   INTO   v_StationNo,v_LinkPhone,v_IsUse;     
              EXIT   WHEN   s_cursor%NOTFOUND;       
                begin     
                   select   stationno     from   StationBaseInfo   where   stationno=v_StationNo; 
                  update     StationBaseInfo   set   LinkPhone=v_LinkPhone,IsUse=v_IsUse   where   StationNo=v_StationNo; 
                EXCEPTION 
                    WHEN   NO_DATA_FOUND   THEN     --如果不存在,插入新数据 
                          insert   into   StationBaseInfo(StationNo,LinkPhone,IsUse)values(v_StationNo,v_LinkPhone,v_IsUse); 
                end;
          END   LOOP;     
        CLOSE   s_cursor; 
        commit; 
    end;
    不过我一般会这样做CURSOR   s_cursor   IS   SELECT   IsUse,OFFICE_TEL,ACTIVE_STATUS   FROM   BS_STATION_M; 
    begin 
      SET   SERVERIUTPUT   ON 
      DECLARE   
              v_StationNo   StationBaseInfo.StationNo%TYPE;     
              v_LinkPhone   StationBaseInfo.LinkPhone%TYPE; 
              v_IsUse   StationBaseInfo.IsUse%TYPE; 
              flag      number;        
        OPEN   s_cursor;     --打开游标 
          LOOP     --循环游标读取数据 
              FETCH   s_cursor   INTO   v_StationNo,v_LinkPhone,v_IsUse;     
              EXIT   WHEN   s_cursor%NOTFOUND;       
                   
                   select  count(*) into flag     from   StationBaseInfo   where   stationno=v_StationNo;
                   if (flag>0) then
                       update     StationBaseInfo   set   LinkPhone=v_LinkPhone,IsUse=v_IsUse   where   StationNo=v_StationNo;
                   else 
                        insert   into   StationBaseInfo(StationNo,LinkPhone,IsUse)values(v_StationNo,v_LinkPhone,v_IsUse); 
                   end if;
               
          END   LOOP;     
        CLOSE   s_cursor; 
        commit; 
    end;
      

  2.   

    上面的写法都复杂了.
    以下方法对操作几百条数据,,速度也挺快的..个人测试过
    原理是这样的.
    比如 源表A 目标表 B (表结构一样)
    临时表 C D1.把 B表中存在的,A也存在的,把要更新的放进C
    这个insert into 很快的.
    2.把A不在C中的,插入D,把B不在C中的插入D中,
    最后把D插入C.
    3,删除临时表D
    4,删除目标表B
    5,把C改名B.并且建立相关索引等..大概原理是这样..处理大数量非常有用.
      

  3.   

    谢谢你的回答,但还是编译不过去:
    代码如下:
     as
    CURSOR   s_cursor   IS   SELECT   IsUse,OFFICE_TEL,ACTIVE_STATUS   FROM   BS_STATION_M; 
    begin 
      SET   SERVERIUTPUT   ON 
      DECLARE   
              v_StationNo   StationBaseInfo.StationNo%TYPE;     
              v_LinkPhone   StationBaseInfo.LinkPhone%TYPE; 
              v_IsUse   StationBaseInfo.IsUse%TYPE; 
              flag      number;        
        OPEN   s_cursor;     --打开游标 
          LOOP     --循环游标读取数据 
              FETCH   s_cursor   INTO   v_StationNo,v_LinkPhone,v_IsUse;     
              EXIT   WHEN   s_cursor%NOTFOUND;       
                   
                   select  count(*) into flag     from   StationBaseInfo   where   stationno=v_StationNo;
                   if (flag>0) then
                       update     StationBaseInfo   set   LinkPhone=v_LinkPhone,IsUse=v_IsUse   where   StationNo=v_StationNo;
                   else 
                        insert   into   StationBaseInfo(StationNo,LinkPhone,IsUse)values(v_StationNo,v_LinkPhone,v_IsUse); 
                   end if;
               
          END   LOOP;     
        CLOSE   s_cursor; 
        commit; 
    end;错误提示为:
    行号= 4 列号= 9 错误文本= PL/SQL: ORA-00922: 缺少或无效选项
    行号= 4 列号= 3 错误文本= PL/SQL: SQL Statement ignored
    行号= 7 列号= 25 错误文本= PLS-00103: 出现符号 "STATIONBASEINFO"在需要下列之一时:  := . ( @ % ; 符号 ":=" 被替换为 "STATIONBASEINFO" 后继续。 
    行号= 8 列号= 21 错误文本= PLS-00103: 出现符号 "STATIONBASEINFO"在需要下列之一时:  := . ( @ % ; 符号 ":=" 被替换为 "STATIONBASEINFO" 后继续。 
    行号= 9 列号= 21 错误文本= PLS-00103: 出现符号 "NUMBER"在需要下列之一时:  := . ( @ % ; 符号 ":=" 被替换为 "NUMBER" 后继续。 这是什么原因?我的数据库用的是ORacle9i。谢谢
      

  4.   

    新手过来学习。ORA-00922的意义:
    An invalid option was specified in defining a column or storage clause. The valid option in specifying a column is NOT NULL to specify that the column cannot contain any NULL values. Only constraints may follow the datatype. Specifying a maximum length on a DATE or LONG datatype also causes this error.
    改正方法:Correct the syntax. Remove the erroneous option or length specification from the column or storage specification.太难懂了,帮你顶一下吧。另外请教为什么前面加一个最开始加一个'as'?还有 'SET       SERVERIUTPUT       ON  '什么意思?