一段存储过程请教

[复制链接]
查看11 | 回复9 | 2012-1-4 11:56:44 | 显示全部楼层 |阅读模式
本人对代码不太懂。特来请教下面的代码是什么意思。自己只看懂了:把库里所有WANGWANG开头的表的列取出,插到HEHE用户里。是这样吗?
PROCEDURE test(tablenames in varray_tables)
as
userid varchar2(20);
cursor userinfos is select username from dba_users where username like 'WANGWANG%';
strsql varchar2(32767);
idcolumn varchar2(30);
idsql varchar2(500);
tablename varchar2(100);
columnnames varchar2(32767);
querycolumnnamessql varchar2(32767);
cursor colnamescursor(un varchar2,tabname varchar2) is select COLUMN_NAME from dba_tab_columns where owner=un and table_name=tabname;
v_file_handle utl_file.file_type;
begin
v_file_handle:=utl_file.fopen('PLOG_DIR','hehelog.log','w',32767);
utl_file.put_line(v_file_handle,'begin merge server=========');
utl_file.fflush(v_file_handle);
For user in userinfos loop
begin

for x in 1..tablenames.count loop

begin

tablename :=tablenames(x);

userid := SUBSTR(user.username, INSTR(user.username, 'WANGWANG', 1,1)+length('WANGWANG'),length(user.username)-length('WANGWANG'));

idsql:=q''||tablename ||q''||user.username||q'';

dbms_output.put_line(idsql||'====== '||idcolumn);

utl_file.put_line(v_file_handle,idsql||'====== '||idcolumn);

utl_file.fflush(v_file_handle);

execute immediate idsql into idcolumn;


columnnames := '';

for colscur in colnamescursor(user.username,UPPER(tablename)) loop

columnnames := columnnames || colscur.COLUMN_NAME || ',';

end loop;


columnnames := substr(columnnames,1,length(columnnames)-1);

strsql := 'insert into hehe.'||tablename||'('||columnnames||')select'|| columnnames || ' from '||user.username||'.'||tablename||q''||tablename||q''||idcolumn||q''||userid||q''||idcolumn||q''||idcolumn||q'';

execute immediate strsql;

dbms_output.put_line(strsql||'======update '||SQL%ROWCOUNT ||' rows '|| columnnames);

utl_file.put_line(v_file_handle,tablename||'======update '||SQL%ROWCOUNT ||' rows' || columnnames);

utl_file.fflush(v_file_handle);

commit;


columnnames := '';

for colscur in colnamescursor(user.username,UPPER(tablename)||'_SEC') loop

columnnames := columnnames || colscur.COLUMN_NAME || ',';

end loop;

columnnames := substr(columnnames,1,length(columnnames)-1);


strsql := 'insert into hehe.'||tablename||'_SEC ('||columnnames||')
select'|| columnnames || ' from '||user.username||'.'||tablename||q''||tablename||q''||idcolumn||q''||userid||q''||idcolumn||q''||idcolumn||q'';

execute immediate strsql;

dbms_output.put_line(strsql||'======update '||SQL%ROWCOUNT ||' rows ' || columnnames);

utl_file.put_line(v_file_handle,tablename||'_SEC======update '||SQL%ROWCOUNT ||' rows ' || columnnames);

utl_file.fflush(v_file_handle);

commit;

EXCEPTION

WHEN OTHERS THEN

rollback;

DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||strsql||idsql||'============='||SQLERRM);

utl_file.put_line(v_file_handle,SQLCODE||'---'||tablename||idsql||'============='||SQLERRM);

utl_file.fflush(v_file_handle);

end;

END LOOP;
end;
End loop;

DBMS_OUTPUT.PUT_LINE('end merge server=========');
utl_file.put_line(v_file_handle,'end merge server=========');
utl_file.fflush(v_file_handle);
utl_file.fclose(v_file_handle);
EXCEPTION
WHEN OTHERS THEN
rollback;
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---============='||SQLERRM);
utl_file.put_line(v_file_handle,SQLCODE||'---============='||SQLERRM);
utl_file.fclose(v_file_handle);
end;

回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
本帖最后由 DJQTDJ 于 2015-8-11 17:25 编辑
-- 下次请先把格式调调PROCEDURE TEST(
TABLENAMES IN VARRAY_TABLES)AS--V_FILE_HANDLE
UTL_FILE.FILE_TYPE;USERID
VARCHAR2(20);STRSQL
VARCHAR2(32767);IDCOLUMN
VARCHAR2(30);IDSQL
VARCHAR2(500);TABLENAME
VARCHAR2(100);COLUMNNAMES
VARCHAR2(32767);QUERYCOLUMNNAMESSQLVARCHAR2(32767);--CURSOR USERINFOS IS
SELECTUSERNAME
FROMDBA_USERS
WHEREUSERNAME LIKE 'WANGWANG%';--CURSOR COLNAMESCURSOR(UN VARCHAR2,TABNAME VARCHAR2) IS
SELECTCOLUMN_NAME
FROMDBA_TAB_COLUMNS
WHEREOWNER = UN
AND
TABLE_NAME=TABNAME;--BEGIN---- 打开文件句柄V_FILE_HANDLE:=UTL_FILE.FOPEN('PLOG_DIR','HEHELOG.LOG','W',32767);-- 写文件 的第一行UTL_FILE.PUT_LINE(V_FILE_HANDLE,'BEGIN MERGE SERVER=========');-- 清除缓存 这TM是谁写的,你就PUT_LINE 请个毛,又不是RAWUTL_FILE.FFLUSH(V_FILE_HANDLE);---- 下面估计是正题 打开游标 得到了 USERNAME 集合FOR USER IN USERINFOS LOOP
BEGIN
-- 遍历引数表名集合,虽然不知道是个啥
FOR X IN 1..TABLENAMES.COUNT LOOP
BEGIN
-- 获取表名
TABLENAME :=TABLENAMES(X);--
-- 获取USERNAME的WANGWANG往后的几个字符
USERID := SUBSTR(USER.USERNAME, INSTR(USER.USERNAME, 'WANGWANG', 1,1)+LENGTH('WANGWANG'),LENGTH(USER.USERNAME)-LENGTH('WANGWANG'));--
-- 获取列明 首先用户名是WANGWANG的约束是PK的表还是上面那些
IDSQL:=Q''||TABLENAME ||Q''||USER.USERNAME||Q'';--
-- 往文件里面写这个SQL文
DBMS_OUTPUT.PUT_LINE(IDSQL||'====== '||IDCOLUMN);
-- 第一次写的这个没有列名
UTL_FILE.PUT_LINE(V_FILE_HANDLE,IDSQL||'====== '||IDCOLUMN);
-- 清除缓存
UTL_FILE.FFLUSH(V_FILE_HANDLE);--
-- 得到列明 这个除非你这个就一列不然没啥子用
EXECUTE IMMEDIATE IDSQL INTO IDCOLUMN;--
-- 这个应该是列明的另一个对象
COLUMNNAMES := '';--
-- 获取拥有者是类似WANG的,表是上面检索的,到这里我估计我已经猜出来了
FOR COLSCUR IN COLNAMESCURSOR(USER.USERNAME,UPPER(TABLENAME)) LOOP--
-- 拼列明
COLUMNNAMES := COLUMNNAMES || COLSCUR.COLUMN_NAME || ',';--
END LOOP;--
-- 把最后一个逗号去了,要整个的列,参照上次吧友的问题,如何整列名然后用逗号隔开,不过这程序写的很垃圾
COLUMNNAMES := SUBSTR(COLUMNNAMES,1,LENGTH(COLUMNNAMES)-1);--
-- 把这堆玩意往HEHE的用户里面插,就是类似创建一个和WANGWANG一样的表
STRSQL := 'INSERT INTO HEHE.'||TABLENAME||'('||COLUMNNAMES||')SELECT'|| COLUMNNAMES || ' FROM '||USER.USERNAME||'.'||TABLENAME||Q''||TABLENAME||Q''||IDCOLUMN||Q''||USERID||Q''||IDCOLUMN||Q''||IDCOLUMN||Q'';--
-- 开始干
EXECUTE IMMEDIATE STRSQL;--
-- 更新了多少行
DBMS_OUTPUT.PUT_LINE(STRSQL||'======UPDATE '||SQL%ROWCOUNT ||' ROWS '|| COLUMNNAMES);--
-- 在文件里面写更新了哪个表更新了多少行
UTL_FILE.PUT_LINE(V_FILE_HANDLE,TABLENAME||'======UPDATE '||SQL%ROWCOUNT ||' ROWS' || COLUMNNAMES);
-- 清除缓存
UTL_FILE.FFLUSH(V_FILE_HANDLE);
-- コミット
COMMIT;--
-- 列明清空
COLUMNNAMES := '';
-- 看有没有带_SEC的表,和上述一样,我就不写注释了
FOR COLSCUR IN COLNAMESCURSOR(USER.USERNAME,UPPER(TABLENAME)||'_SEC') LOOP
COLUMNNAMES := COLUMNNAMES || COLSCUR.COLUMN_NAME || ',';
END LOOP;
COLUMNNAMES := SUBSTR(COLUMNNAMES,1,LENGTH(COLUMNNAMES)-1);
STRSQL := 'INSERT INTO HEHE.'||TABLENAME||'_SEC ('||COLUMNNAMES||')SELECT'|| COLUMNNAMES || ' FROM '||USER.USERNAME||'.'||TABLENAME||Q''||TABLENAME||Q''||IDCOLUMN||Q''||USERID||Q''||IDCOLUMN||Q''||IDCOLUMN||Q'';
EXECUTE IMMEDIATE STRSQL;
DBMS_OUTPUT.PUT_LINE(STRSQL||'======UPDATE '||SQL%ROWCOUNT ||' ROWS ' || COLUMNNAMES);
UTL_FILE.PUT_LINE(V_FILE_HANDLE,TABLENAME||'_SEC======UPDATE '||SQL%ROWCOUNT ||' ROWS ' || COLUMNNAMES);
UTL_FILE.FFLUSH(V_FILE_HANDLE);
COMMIT;
EXCEPTION
-- 有错误在文件里面写错误
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||STRSQL||IDSQL||'============='||SQLERRM);
UTL_FILE.PUT_LINE(V_FILE_HANDLE,SQLCODE||'---'||TABLENAME||IDSQL||'============='||SQLERRM);
UTL_FILE.FFLUSH(V_FILE_HANDLE);
END;
END LOOP;
END;END LOOP;---- 用户迁移成功DBMS_OUTPUT.PUT_LINE('END MERGE SERVER=========');UTL_FILE.PUT_LINE(V_FILE_HANDLE,'END MERGE SERVER=========');UTL_FILE.FFLUSH(V_FILE_HANDLE);UTL_FILE.FCLOSE(V_FILE_HANDLE);-- 有错误在文件里面写错误EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||STRSQL||IDSQL||'============='||SQLERRM);
UTL_FILE.PUT_LINE(V_FILE_HANDLE,SQLCODE||'---'||TABLENAME||IDSQL||'============='||SQLERRM);
UTL_FILE.FFLUSH(V_FILE_HANDLE);END;你只说对了一半,剩下的你看注释自己看把,我已经不想解答了,还有这存储过程谁写的,在这里我觉得我只能用IRON MAN 2里面IVAN对HAMMER说的一句话来形容了:PROGRAM IS SHIT复制代码
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
不是WANGWANG开头的表,而是以WANGWANG开头的用户,将入参tablenames中指定的表,按指定的条件,插入到相应的HEHE用户下的相应表中。
以上所有的操作的代码和执行结果,记入位于PLOG_DIR中指定目录下的文件hehelog.log中。
你可以将相应的insert语句注释掉,然后执行该存储过程,直接看输出或查看前述的hehelog.log文件的内容会更直观。
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
本帖最后由 DJQTDJ 于 2015-8-11 17:31 编辑
顺便求送个马上有对象的徽章,我可以拿狮子座徽章换
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
DJQTDJ 发表于 2015-8-11 17:23
非常感谢。下次一定弄弄格式。解释的好详细。公司的一个开发写的。主要实现功能就是想把库里所有WANGWANG开头的用户下的数据,全部插入到HEHE用户下。WANGWANG用户下的表及结构与HEHE完全一致。我也觉得有点绕。但是用存储过程我也不会实现,只知道用IMPDP把WANGWANG数据APPEND进去。
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
DJQTDJ 发表于 2015-8-11 17:30
顺便求送个马上有对象的徽章,我可以拿狮子座徽章换

怎么操作?我跟你换。你是单身吗?


回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
bfc99 发表于 2015-8-11 17:24
不是WANGWANG开头的表,而是以WANGWANG开头的用户,将入参tablenames中指定的表,按指定的条件,插入到相应 ...

嗯谢谢提醒
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
EXCEPTION

WHEN OTHERS
明显是懒惰
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
xteitxu 发表于 2015-8-11 19:26
怎么操作?我跟你换。你是单身吗?

的确,我是单身的屌丝程序员,点自己头像,有个更新资料,徽章管理,选择徽章选择批量转让,然后把我ID放进去顺便输入自己密码就行了,我先吧狮子座给你
回复

使用道具 举报

千问 | 2012-1-4 11:56:44 | 显示全部楼层
xteitxu 发表于 2015-8-11 19:27
嗯谢谢提醒

嗯 转让成功了 你自己在徽章那里看看,狮子座给你了,你那个马上有对象求送
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行