Sybase中的BCP用法实践 与 Oracle的SQLLDR用法实践

  关于BCP的用法法,网上有很多资料,但要经过自已的实践来证实才能为已所用,因网上的东东有些是转来转去,会有遗误之处,所以对网上的相关资料要广泛地多多地参考,不能迷信某一家之言,因为IT相关的东东存于着不同的平台不同版本不同的习惯不同的定势,所以也就会有任何可能和不可能的事情发生,本人实践平台都是有Windows 2003 server下的,Sybase ASE 12.5的,Oracle9i
关于BCP的导出导入,需要注意的是:如果从一个sybase库中导到另一个sybase库中,参数选取很重要:
提倡后面用-n参数,不能用-c,因为-n是以二进制来导的,而-c是以文件内容来导的,由于存在字符编码不同,如果用-c可能会出现乱码现象;但如果你要是用BCP导出的数据(data.txt格式)需要往Oracle中导入的话,则一定要用-c参数;-t后面跟的是分隔符,可以用","或"|"来分隔,建议用"|",不容易与某些字段内容干扰;
Sybase BCP导出语法:
BCP datasource.dbo.pub_goods out data/pub_goods.txt -Uuser -Ppassword -Sservice -t, -n
说明:datasource是数据源,就和master是一个等级,如果你的表是在master下建的,那datasource就是master;dbo属主不用说了吧(有些文章用省掉了,如:datasource..pub_goods ,我试了不行,害的我浪费了很多时间);pub_goods是表名;out是导出,换成in就是导入;


data/pub_goods.txt将导出的文件存在当前目录下的data目录下,并命名为pub_goods.txt;-S是数据库服务名,
Sybase BCP的导入:
BCP datasource.dbo.pub_goods in data/pub_goods.txt -Uuser -Ppassword -Sservice -t, -n

假设我的Sybase数据库中的数据库服务名是SHERP;建了一个SHPOS的数据源,SHPOS下有个表pub_goods
Oracle9i的数据源名是:ORA_SHERP,在ORA_SHERP中建一个与Sybase中SHPOS下同样的pub_goods表,
要注意oracle与Sybase的字段类型有差异的,特别的,如sybase中SMALLMONEY 值的范围为 -214 748.3648 到 214 748.3647,
那在oracle中就设number(12,4)应该能装下这个数据类型的;如果有类型不明确,在oracle中直接用char来的替代,
用的时候要根据需要再转换;Sybase库中的用户名sa,密码为空:


从Sybase库中把pub_goods表中数据全部导出,当然我们要根据自已需要的条件来导出需要的数据;
首先我们需要对Sybase中的日期格式要转换一下,否则Oracle中不识别,可以考虑的方法是建一个视图
将日期格式转换过来:如:
creat view v_pub_goods as select pub_goods,pub_goodsname,pub_class,pub_price,
convert(char(10),createdate ,111)+' '+(convert(char(8),createdate,108)) as createdate from pub_goods
然再执行导出工作:
BCP SHPOS.dbo.pub_goods out data/pub_goods.txt -Usa -P -SSHERP -t"|" -c

——当然也可以用Sybase中的isql工具,省去建视图或临时库的中间过程;isql用法:
D:\>isql -Usa -P -w1000 -s"|" -i sql/pub_goods.sql -o data/pub_goods.txt
首先要将CMD的缓冲区调的中够宽——CMD属性—>布局—>屏幕缓冲区大小和窗口大小全部调成10000好啦,
具体大小可以根据表的行最大字符数来算;-w1000缓冲区宽度;-s"|"类似于BCP中的-t"|";
-i sql/pub_goods.sql在当前目录的sql目录下建一个pub_goods.sql文档,就是select语句,内容如下:
select pub_goods,pub_goodsname,pub_class,pub_price,
convert(char(10),createdate ,111)+' '+(convert(char(8),createdate,108)) as createdate from pub_goods
说明一下:因为isql导出的数据文件较大,且在下面往Oracle中用sqlldr导入时,写CTL控制文件较麻烦的,
由于存在全是"|"分隔符的空列,所在CTL控制文件第一列前还要加一行:null filler, 
并且对空值处理易出错,所以建议初哥还是用BCP,SCO unix平台的Sybase是也支持select条件导出,而且微软的SQLSERVER
的BCP工具支持的格式花样更多;不知为何Windows平台下Sybase中的BCP不能用Select条件导出,搞不明白!~!@#$%&!

下一步,开始往Oracle数据库的pub_goods表中导数,准备工作:
当前目录下准备建两个文本文件pub_goods.par和pub_goods.ctl

pub_goods.par文件内容如下:
--------------------------------------
userid=user@ORA_SHERP //也可以user/password@ORA_SHERP 省略密码,运行时会提示让你输入密码
control=pub_goods.ctl //就是上面提到的控制文件
bad=log/pub_goods.bad //坏记录存入路径,就没没有导进去的那条记录;
log=log/pub_goods.log //完整记录,这个里面你可以查到相关日志,特别是失败记录有详细说明;
errors=500 //允许的错误记录行数,错误记录达到这个数就停止sqlldr
skip=0 //忽略第0行,一般我们看数据文件格式,如果有一行字段头的就写skip=1
rows=50 //绑定数组: 50 行,最大 256000 字节,每多少行一提交
//direct=true //该参数是直接路径装载,会卸载表的一些索引约束等,会很快,
//但装完后要确认或重建索引约束;默认是false, 
--------------------------------------

pub_goods.ctl文件内容如下:
---------------------------------------------------
load data
infile 'data/pub_goods.txt' //数据文件路径
truncate into table pub_goods
FIELDS terminated by '|' --//数据文件中的分隔符
TRAILING NULLCOLS --//忽略空值

( --// 如果你在这里加上:null filler, 表示取消第一个空列全是"|"的影响,否则系统会把最头的一个"|"列当成第一列
--//这个原因是由于你用isql工具导数引起,用BCP就完全不用担心这个问题
pub_goods,
pub_goodsname,
pub_class,
pub_price,
createdate timestamp "YYYY/MM/DD HH24:MI:SS" --//按照pub_goods.txt数据文件的时间格式来装载,
--//需要说明的是:可以在这之后加上nullif createdate ="1900/01/01 00:00:00" 
-- //如果字段为空值就返一个"1900/01/01 00:00:00" 值,否则非char类的空值数据导入会不成功,
-- // 当然也以可用变通方法:如:pub_price filler char 人为强制定义pub_price这个列以char类型导入
-- //若是:pub_price filler (注意:这里加上filler是装载时忽略这一列,不装载这一列) 
)
----------------------------------------------------------------
上面--//以及后面的内容全是注释,实际操作中可以全去掉;

如果全部准备好了!打开CMD,输入:sqlldr parfile=pub_goods.par
就可看到运行结果了,可能会失败,并且N次失败,



如果导入有失败记录,检查log=log/pub_goods.log 和bad=log/pub_goods.bad 内容,
是数据文件有问题? column sex长度过大过小? 检查数据文件和表结构 

如有疑问或有更好的解决方案请信至:[email protected],需要探讨,请告之于MSN

以下用SQLLDR工具导入的批处理:确保当前目录下有log和data目录,确保当前目录有“表名.ctl ”和“表名.par” 
data目录下有“表名.txt”——用BCP导出的数据文件;强烈此前手工导一遍确定可行,相关文件名规则按表名命名



rem ********************************************************************
rem ********************************************************************
rem ****执行将刚才用ISQL导出的数据用sqlldr 导入到Oracle中相应的表中*****
rem ********************************************************************
rem ********************************************************************

@echo off
COLOR 0A
cls
echo .该程序的执行码默认是yolo
SET /P VAL=.请输入本次执行码:
IF NOT "%VAL%"=="yolo" GOTO END
ECHO .执行码检查完毕!!!!!
SET /P ClsTNS1=请输入要导入的数据库名称:
SET /P table1=请输入你要导入的%ClsTNS1%表名:
set /p user1=请输入%ClsTNS1%数据库的用户名:
cls
rem ##########<<<<<为了保密起见,用利用汇编方式隐藏输出显示>>>>>################
echo ////////////////////////////////////////////////////
echo / 密码都被隐藏处理,操作者将看不到屏幕显示 ///////// 
echo / 输完直接回车!按屏幕提示操作,请稍候......//////// 
ECHO ////////////////////////////////////////////////////
rem ###下面的是屏幕延时显示###
ping 127.1>nul
rem ######ping 127.1>nul
rem ####################################################################

cls
@echo off 
chcp 437>nul&graftabl 936>nul
echo hP1X500P[PZBBBfh#b##fXf-V@`$fPf]f3/f1/5++u5x>in.com
set /p password1=请输入密码(屏幕输入已作隐藏处理): for /f "tokens=*" %%i in ('in.com') do set password1=%%i
del in.com
cls
rem #################################################################

cls
echo 你即将导入的是%ClsTNS1%数据库,%user1%用户下的%table1%表,请核实。。。。。。
echo 正在准备执行sqlldr向oracle数据库导入操作,确认按任意键执行导出......
pause
echo 再次提醒您一次:你导的是%ClsTNS1%数据库下%user1%用户下的%table1%表,
echo 因为该操作是直接向数据库中写数据,误操作会导致不可挽回后果,,,,,
echo 本制作人不负责任何后果!
pause
pause
rem ##########################<<<<<执行代码>>>>>#######################

@ECHO off

sqlldr %user1%/%password1%@%ClsTNS1% control=%table1%.ctl log=log\sqlldr%table1%.log bad=log\sqlldr%table1%.bad data=data\%

table1%.txt

rem ##############给用户观察到结果状态##############
ping 127.1>nul


rem 可以将sqlldr 这个语法句子固化,通过批处可实现按计划任务定期导入,
rem bad=log\sqlldr%table%.bat变为
rem bad=log\sqlldr%table%%date:~0,10%bat来实现按日期或时间命名,
rem 具体日期时间格式自已试;当然前提是:
rem BCP导入的数据文件也要按需要的计划任务定期导出到date目录下  

你可能感兴趣的:(oracle,数据库,user,table,Sybase,sqlserver)