我有两个数据表分别为: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;
更新原则是:如果目的表中存在源表中的数据,就用源表中的数据更新目的表中的数据,如果不存在就将源表中的数据插入到目的表中。 以下是我写的存储过程,老是包错,请各位指点帮忙修改一下,谢谢: 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;
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;
以下方法对操作几百条数据,,速度也挺快的..个人测试过
原理是这样的.
比如 源表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.并且建立相关索引等..大概原理是这样..处理大数量非常有用.
代码如下:
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。谢谢
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 '什么意思?