马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?站点注册
×
在一个应用系统中,如果编写了大量的Sybase存储过程,对存储过程进行系统、有效地备份是必须的。而我们通常用的办法是使用Sybase提供的Sybase Central工具先选定存储过程,然后通过鼠标右键选择Generate DDL的方式把存储过程备份下来。使用这种方式,不仅备份时间特别长(备份文件为6M左右时,达几个小时之久),更要命的是使用该方式备份下来的存储过程文本往往无法直接使用,因为在每个存储过程体后自动加的关键字go,有时就直接放在过程体最后一行尾部,没有空格,这样要使用该文本重新建过程时,需要花大量的时间进行修正。因此,找一种备份速度既快备份后内容又规整的方法来替代该工具是完全有必要的。 |
笔者在实际工作中,交叉使用以下两种方法,对存储过程进行备份。方法一:通过编写嵌入sql的C程序,实现整库存储过程的快速导出。方法二:通过defncopy快速导出指定的存储过程。现分别详细介绍如下: |
以下程序通过sybase的cpre预编译处理生成可执行文件后,可以实现存储过程的快速导出,在数据库空闲时,可以在一分钟之内导出所有的存储过程(生成的文件有6M左右,而Sybase Central需要以小时计)。 |
该程序运行时格式如下(设可执行文件为exportproc): |
执行完后,所有的存储过程体就存放在该文件中,文件的内容也保存了存储过程的书写格式,并在每个存储过程后面加一个单独的行go。为了使程序灵活,在正式导之前根据提示需要输入用户名、口令、联机串、数据库名。 |
char useName[11], usePasswd[11], dbString[16]; |
EXEC SQL BEGIN DECLARE SECTION; |
EXEC SQL END DECLARE SECTION; |
printf("Usage As %s <fileName>\n", argv[0]); |
if( (fp=fopen(argv[1],"w+"))==NULL){ |
printf("Open file %s error\n",argv[1]); |
printf("Please Input user name:"); |
fpass=getpass("Please Input Passwd:"); |
printf("Please Input Database string:"); |
printf("Please Input Database Name:"); |
EXEC SQL WHENEVER SQLERROR CALL Sql_Error(); |
if( ConnectDB(useName, usePasswd, dbString) !=0){ /*连接数据库*/ |
printf("Can't connect database\n"); |
printf("Connect database ok!\n"); |
printf("Begin to export PROCEDURE Please wait...\n"); |
/*声明游标,找出该库中所有的存储过程对应的内容*/ |
EXEC SQL declare pro_cur cursor for |
SELECT id, text from syscomments |
where id in (select id from sysobjects |
order by id, number,colid2,colid; |
EXEC SQL FETCH pro_cur into :id, :textLine; |
if( id!=oldId && oldId!=-9999L){ |
/*当一个存储过程结束后,在其过程体后加入新行GO*/ |
fprintf(fp,"%s",textLine); |
EXEC SQL FETCH pro_cur INTO :id, :textLine; |
printf("End export PROCEDURE !\n"); |
printf("Disconnect DataBase success!\n"); |
EXEC SQL WHENEVER SQLERROR CONTINUE; |
printf("%s\n",sqlca.sqlerrm.sqlerrmc); |
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; |
该程序在IBM AIX4.3、hp-unix 11.0、tru64 unix5.0平台上测试通过。 |
在需要对一些存储过程单独进行备份时,往往使用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%" |
isql -U用户名 -P口令 -S联机串名 –I crtprocout.sql –o procout |
4.执行脚本导出过程,每个过程脚本名为:过程名+后缀”.sql” |
小结:以上两种办法通过修改sql语句里的where条件相互之间是可以代替的。但笔者认为,前者适合对整库的过程进行备份,而后者适合对指定的几个过程进行备份。因为前者会对所有的过程脚本生成到一个文件里,适合面向多个过程的管理和备份;而后者一个过程脚本生成一个文件,适合面向单个过程的管理和备份。以上两种方法通过简单修改也可进行触发器等的导出。 | http://www.ccw.com.cn/htm/center/skill/02_7_25_2.asp |