使用Oracle sqlldr遇到ORA-12545: Connect failed... 和 ORA-12154: TNS:could not resolve...报错

背景

在 Oracle 数据库中,通常需要在不同数据库的表里的记录进行复制或迁移。会用以下几种方法:

  1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中
  2. 建立数据库间的 dblink,然后用 select into B from A@dblink where …,或 insert into B select * from A@dblink where …
  3. exp A 表,再 imp 到 B 表,exp 时可加查询条件
  4. 程序实现 select from A …,然后 insert into B …,也要分批提交
  5. 再就是使用 Sql Loader(sqlldr) 来导入数据,效果比起逐条 insert 来很明显

操作过程

第一步

先运行cmd,然后输入 sqlldr,执行后看是否有输出结果,结果大概如下:

SQL*Loader: Release 12.2.0.1.0 - Production on Wed Aug 28 20:41:13 2019

Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.

Usage: SQLLDR keyword=value [,keyword=value,...]

Valid Keywords:

    userid -- ORACLE username/password
   control -- control file name
       log -- log file name
       bad -- bad file name
      data -- data file name
   discard -- discard file name
discardmax -- number of discards to allow          (Default all)
      skip -- number of logical records to skip    (Default 0)
      load -- number of logical records to load    (Default all)
    errors -- number of errors to allow            (Default 50)
      rows -- number of rows in conventional path bind array or between direct path data saves
               (Default: Conventional path 64, Direct path all)
  bindsize -- size of conventional path bind array in bytes  (Default 256000)
    silent -- suppress messages during run (header,feedback,errors,discards,partitions)
    direct -- use direct path                      (Default FALSE)
   parfile -- parameter file: name of file that contains parameter specifications
  parallel -- do parallel load                     (Default FALSE)
      file -- file to allocate extents from
      ......

输出以上结果,证明可以使用sqlldr命令。

注意上面输出信息中部分参数的作用

第二步

书写 ctl 控制文件,一般又分两种:

  • 只使用一个控制文件,在这个控制文件中包含数据
  • 使用一个控制文件(作为模板) 和一个数据文件

因为数据量很大,选择第二种。
首先,需要先通过PL/SQL Developer找到数据,然后 导出 csv 数据文件。(导出步骤不再叙述)。例如命名为 data.csv。用文本打开查看,第一行一般都是表头列名。
接着书写ctl文件,如下:- - 后面是解释,真正的文件中,不需要写。

OPTIONS (skip=1,rows=128)  --skip=1 用来跳过数据中的第一行  
LOAD DATA 
INFILE "data.csv"   --指定外部数据文件,可以写多个 INFILE "another_data_file.csv" 指定多个数据文件  
--这里还可以使 用 BADFILE、DISCARDFILE 来指定坏数据和丢弃数据的文件,  
append  --操作类型,在表中追加新记录  
INTO TABLE tableName   -- 要插入记录的表  
Fields terminated by ","    -- 数据中每行记录用 "," 分隔  
Optionally enclosed by '"'    -- 数据中每个字段用 '"' 框起,比如字段中有 "," 分隔符时。可以不写这句话 
trailing nullcols    --表的字段没有对应的值时允 许为空  
(  
  virtual_column FILLER, --这是一个虚拟字段,用来跳 过由 PL/SQL Developer 生成的第一列序号  
  column_namenumber, --字段可以指定类型,否则认 为是 CHARACTER 类型, log 文件中有显示  
  column_name,  
  column_name,  
  date_column_name DATE "YYYY-MM-DD HH24:MI:SS" -- 指定接受日期的格式,相当用 to_date() 函数转换  
) 

说 明:在操作类型 append 位置可用以下中的一值:
1/) insert --为缺省方式,在数据装载开始时要求表为空
2/) append --在表中追加新记录
3/) replace --删除旧记录(用 delete from table 语句),替换成新装载的记录
4/) truncate --删除旧记录(用 truncate table 语句),替换成新装载的记录

例如:

OPTIONS (skip=1)  
LOAD DATA 
INFILE "data.csv"  
append  
INTO TABLE tableName   -- 要插入记录的表  
Fields terminated by ","
Optionally enclosed by '"'
trailing nullcols  
(  
  virtual_column FILLER,  
  column_namenumber,   
  column_name,  
  column_name,  
  date_column_name DATE "YYYY-MM-DD HH24:MI:SS"
) 

保存为load_data.ctl 文件,命名根据自己的来。

第三步

准备好上面两个步骤后开始写sqlldr命令,先进入到上面两个文件的文件夹,然后在这里打开cmd,然后执行下面的命令,数据库相关信息请换成自己的配置:

(1)

sqlldr userid=dbuserName/dbPassword@hostName:portNum:SID control=load_data.ctl 

报错:
SQL*Loader-704: Internal error: ulconnect: OCIServerAttach [0]
ORA-12545: Connect failed because target host or object does not exist

看到这个错误想到的是host识别不出来,于是换成ip地址,还是未解决。

(2)
修改命令:

sqlldr userid=dbuserName/dbPassword@SID control=load_data.ctl 

报错:
SQL*Loader-704: Internal error: ulconnect: OCIServerAttach [0]
ORA-12154: TNS:could not resolve the connect identifier specified

又遇到新的错误。
解决如下!

解决过程

依然使用第二条命令:

sqlldr userid=dbuserName/dbPassword@SID control=load_data.ctl

根据自己机器上oracle的安装路径,找到下面的路径,比如我的机器上的路径如下:

C:\oracle\product\12.2.0.1\client\network\admin\

在该路径下应该会有个sample文件夹,从里面copy一个tnsnames.ora文件,清除掉里面的内容或者新建一个空文件,命名和这个一致,添加内容,格式如下,如果不一致也有可能导致依然报错:<>中是解释

<这条配置的别名> = 
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = <host信息> )(PORT = <端口号>))
    )
    (CONNECT_DATA =
      (SID = <自己的数据库的SID名字>)
    )
  )

例如:

DevDB = 
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 1234.apac.net> )(PORT = 8888))
    )
    (CONNECT_DATA =
      (SID = DevDemo)
    )
  )

相应的sqlldr命令如下:

sqlldr userid=dbuserName/dbPassword@DevDB control=load_data.ctl

执行上面的命令,就可以将csv中的数据导入目标数据库了。
如果下次再往别的数据库导入数据,只需在tnsnames.ora文件增加一段上面的配置,别名不同,配置不同而已,然后更换相应的sqlldr命令即可。

总结

全是自己的一些使用总结,写的不好的地方还请指出。也希望能够帮助到遇到相同问题的朋友。如果觉得有帮助的话,请点个赞吧!

发布了79 篇原创文章 · 获赞 10 · 访问量 8650

猜你喜欢

转载自blog.csdn.net/weixin_44728363/article/details/100126644
今日推荐