Is it possible to use a fully qualified TNS entry using sqlldr bundled with Oracle 10/11?
For example, in SQLPlus:
sqlplus user/password@(description=(address=(host=localhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl))) @script.sql
But using sqlldr (SQL Loader) there appear to be issues with using the TNS entry directly. Specifically:
sqlldr user/password@(description=(address=(host=localhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl))) bad='bad_file.txt' control='control.ctl' data='data.txt' log='log.txt' direct='true'
Here is the error message produced:
LRM-00116: syntax error at 'address' following '('
SQL*Loader: Release 11.2.0.1.0 - Production on Tue Sep 13 15:41:54 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
SQL*Loader-100: Syntax error on command-line
Attempting to encapsulate the TNS entry in quotes produces the same error.
Had a look at the sqlldr documentation, and attempted to use the 'userid' command-line argument to no avail. Specifically:
sqlldr userid='user/password@(description=(address=(host=localhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))' bad='bad.txt' control='control.ctl' data='data.txt' log='log.txt' direct='true'
LRM-00116: syntax error at 'password@(' following '='
SQL*Loader: Release 11.2.0.1.0 - Production on Tue Sep 13 15:44:17 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
SQL*Loader-100: Syntax error on command-line
It makes sense that Oracle would hope to coerce the user to a local instance to mitigate I/O in pushing data to a remote host. But the deviation in supported syntax is not so intuitive. Anyone else experience similar issues?
SQL*Loader loads data from external files into tables of an Oracle database. It has a powerful data parsing engine that puts little limitation on the format of the data in the datafile. You can use SQL*Loader to do the following: Load data across a network.
Invoking SQL*Loader If you invoke SQL*Loader without specifying any parameters, SQL*Loader displays a help screen similar to the following. It lists the available parameters and their default values. > sqlldr . . . Usage: SQLLDR keyword=value [,keyword=value,...]
The TRAILING NULLCOLS clause tells SQL*Loader to treat any relatively positioned columns that are not present in the record as null columns. See Handling Short Records with Missing Data. The remainder of the control file contains the field list, which provides information about column formats in the table being loaded.
fwiw, this guy posted a solution to this problem
http://www.simplemancomplexmachine.com/2011/10/sqlldr-one-liner-to-remote-database.html
Yes there is a one-line solution and you can use a TNS connect string to do this from the command line. The key is formatting the connection string a little different as it must be quoted. Additionally the quotes and parentheses must be escaped (backslashes):
sqlldr userid=dbuser@\"\(description=\(address=\(host=remote.db.com\)\(protocol=tcp\)\(port=1521\)\)\(connect_data=\(sid=dbsid\)\)\)\"/dbpass control=controlfilename.ctl data=data.csv
Note that in the original blog post he had a space in front of '/dbpass'. This causes sqlldr to give the error:
LRM-00112: multiple values not allowed for parameter 'userid'
Looks like you need to escape characters like '(', ')' and '=' with the escape character '\' (i.e. backslash) as explained in here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With