文本版|topic 高级搜索
   名人堂 帮助 论坛制度 意见反馈 | 首页 博客 周新贴 专题 求职 读书
RSS 底部
 
社区导航: 专家门诊   网络技术   操作系统   数据库   程序设计   系统应用   考试认证   CIO及信息化   站长交流   综合交流   下载基地  51CTO产品服务 设为首页 | 收藏本站
51CTO技术论坛» MySQL & PostgreSQL & Sybase » [转帖]如何快速导出SYBASE的存储过程       [ 打印]  [ 订阅]  [ 收藏]  [ 推荐给朋友]   [ 本帖文本页]

论坛跳转:
     
标题: [转载] [转帖]如何快速导出SYBASE的存储过程  ( 查看:780  回复:1 )   
 
lllenxue
副版主  点击可查看详细


十二生肖之狗   双子座   行业勋章   技术勋章   诚信兄弟  
帖子 701
精华 3
无忧币 2912
积分 1089
阅读权限 140
注册日期 2007-3-23
最后登录 2008-8-29 离线

[查看资料]  [发短消息]  [Blog
  QQ       
发表于:2007-9-28 19:14   标题:[转帖]如何快速导出SYBASE的存储过程
上一帖 |
问题的提出

在一个应用系统中,如果编写了大量的Sybase存储过程,对存储过程进行系统、有效地备份是必须的。而我们通常用的办法是使用Sybase提供的Sybase Central工具先选定存储过程,然后通过鼠标右键选择Generate DDL的方式把存储过程备份下来。使用这种方式,不仅备份时间特别长(备份文件为6M左右时,达几个小时之久),更要命的是使用该方式备份下来的存储过程文本往往无法直接使用,因为在每个存储过程体后自动加的关键字go,有时就直接放在过程体最后一行尾部,没有空格,这样要使用该文本重新建过程时,需要花大量的时间进行修正。因此,找一种备份速度既快备份后内容又规整的方法来替代该工具是完全有必要的。

笔者在实际工作中,交*使用以下两种方法,对存储过程进行备份。方法一:通过编写嵌入sql的C程序,实现整库存储过程的快速导出。方法二:通过defncopy快速导出指定的存储过程。现分别详细介绍如下:

方法一:通过cpre实现快速导出

以下程序通过sybase的cpre预编译处理生成可执行文件后,可以实现存储过程的快速导出,在数据库空闲时,可以在一分钟之内导出所有的存储过程(生成的文件有6M左右,而Sybase Central需要以小时计)。

该程序运行时格式如下(设可执行文件为exportproc):

sybase> exprotproc 文件名

执行完后,所有的存储过程体就存放在该文件中,文件的内容也保存了存储过程的书写格式,并在每个存储过程后面加一个单独的行go。为了使程序灵活,在正式导之前根据提示需要输入用户名、口令、联机串、数据库名。

#include

#include

EXEC SQL INCLUDE SQLCA;

void Sql_Error();

main( argc, argv)

int argc;

char **argv;

{

FILE *fp;

char useName[11], usePasswd[11], dbString[16];

char *fpass;

long oldId;

EXEC SQL BEGIN DECLARE SECTION;

char textLine[256];

long id;

char dbName[20];

EXEC SQL END DECLARE SECTION;

/*输入参数不够,给出使用提示*/

if (argc!=2){

printf("Usage As %s \n", argv[0]);

exit(0);

}

if( (fp=fopen(argv[1],"w+"))==NULL){

printf("Open file %s error\n",argv[1]);

exit(0);

}

/*输入联库用户名*/

printf("Please Input user name:");

gets(useName);

/*输入用户口令,在输入时屏幕不显示输入内容*/

fpass=getpass("Please Input Passwd:");

strcpy(usePasswd,fpass);

/*输入联库字符串*/

printf("Please Input Database string:");

gets(dbString);

/*输入要导出其中存储过程的库名*/

printf("Please Input Database Name:");

gets(dbName);

EXEC SQL WHENEVER SQLERROR CALL Sql_Error();

if( ConnectDB(useName, usePasswd, dbString) !=0){ /*连接数据库*/

printf("Can't connect database\n");

exit(0);

}

else

printf("Connect database ok!\n");

printf("Begin to export PROCEDURE Please wait...\n");

EXEC SQL use :dbName;

EXEC SQL commit;

/*声明游标,找出该库中所有的存储过程对应的内容*/

EXEC SQL declare pro_cur cursor for

SELECT id, text from syscomments

where id in (select id from sysobjects

where type = 'P')

and texttype=0

and text is not null

order by id, number,colid2,colid;

EXEC SQL OPEN pro_cur;

EXEC SQL FETCH pro_cur into :id, :textLine;

oldId=-9999L;

while(!sqlca.sqlcode){

if( id!=oldId && oldId!=-9999L){

/*当一个存储过程结束后,在其过程体后加入新行GO*/

fprintf(fp,"\nGO\n\n");

}

oldId=id;

fprintf(fp,"%s",textLine);

EXEC SQL FETCH pro_cur INTO :id, :textLine;

}

EXEC SQL CLOSE pro_cur;

fprintf(fp,"\nGO\n\n");

fclose(fp);

printf("End export PROCEDURE !\n");

/*断开于数据库的连接*/

DisConnectDB();

printf("Disconnect DataBase success!\n");

}

void Sql_Error()

{

EXEC SQL WHENEVER SQLERROR CONTINUE;

printf("Error.\n");

printf("%s\n",sqlca.sqlerrm.sqlerrmc);

exit(0);

}

/*连接数据库函数*/

int ConnectDB( username, password, dbstring)

EXEC SQL BEGIN DECLARE SECTION;

CS_CHAR *username,*password,*dbstring;

EXEC SQL END DECLARE SECTION;

{

EXEC SQL SET CHAINED OFF;

EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbstring;

return(sqlca.sqlcode);

}

/*断开数据库函数*/

int DisConnectDB()

{

EXEC SQL DISCONNECT ALL;

return 0;

}

该程序在IBM AIX4.3、hp-unix 11.0、tru64 unix5.0平台上测试通过。

方法二:通过defncopy实现快速导出

在需要对一些存储过程单独进行备份时,往往使用defncopy通过拼串的方式进行。具体步骤如下:

1.根据需要备份的存储过程,先编写此crtprocout.sql文件,假设导出所有以PR_JF开头的存储过程,内容如下:

select "defncopy -U用户名 -P口令 -S联机串名 out "+name+".sql 库名 "+name from sysobjects where type='P' and name like "PR_JF%"

2.利用上述文件,生成导过程脚本

isql -U用户名 -P口令 -S联机串名 –I crtprocout.sql –o procout

3.改变文件procout的权限

chmod +x procout

4.执行脚本导出过程,每个过程脚本名为:过程名+后缀”.sql”

./procout

小结:以上两种办法通过修改sql语句里的where条件相互之间是可以代替的。但笔者认为,前者适合对整库的过程进行备份,而后者适合对指定的几个过程进行备份。因为前者会对所有的过程脚本生成到一个文件里,适合面向多个过程的管理和备份;而后者一个过程脚本生成一个文件,适合面向单个过程的管理和备份。以上两种方法通过简单修改也可进行触发器等的导出。http://www.ccw.com.cn/htm/center/skill/02_7_25_2.asp



网络虽虚拟,技术无边界,来看看大家“真面目”!
2007-9-28 19:141楼
[ 顶部 ]
 
ribut9225
主版主  点击可查看详细


开坛元老   内阁大臣   诚信兄弟   主版主专用   巨蟹座  
帖子 3067
精华 1
无忧币 5692
积分 4077
阅读权限 150
来自 (保密)
注册日期 2006-6-22
最后登录 2008-9-6 离线

[查看资料]  [发短消息]  [Blog
  QQ       
发表于:2007-10-9 09:51 
学习了



用户必读,51CTO积分系统调整通知
2007-10-9 09:512楼
[ 顶部 ]
     
论坛跳转:  

| | |

| | |

标记已读 · 删除论坛Cookies · 文本版 · WAP
 
| 诚征版主 | 版主堂 | 意见建议 | 大史记 | 论坛地图
Copyright©2005-2008 51CTO.COM  Powered by Discuz!
本论坛言论纯属发布者个人意见,不代表51CTO网站立场!如有疑义,请与管理员联系。
京ICP备05051492号