Skip to Main Content
  • Questions
  • Calling Export from Pl/sql using C external proc.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Sudee.

Asked: November 16, 2001 - 8:55 pm UTC

Last updated: April 27, 2005 - 9:31 am UTC

Version: 8.1.6

Viewed 1000+ times

You Asked

Hi Tom,

Is there anything wrong with these steps,
the exp does not create a .dmp file.

Thanks


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

__declspec(dllexport) void sh(char *);

void sh( char *cmd )
{
int num;

num = system(cmd);
}


CREATE LIBRARY shell_lib is 'C:\oracle\extproc\shell.dll';


create or replace procedure shell (
cmd IN char)
as external
name "sh"
library shell_lib
language C
parameters (
cmd string);

exec shell('C:\oracle\ora81\bin\exp userid=system/manager file=C:\oracle\extproc\test.dmp full=y rows=N');


and Tom said...

Ok, this is easily solved. What I'll do however is show you the steps I went thru to diagnose this.

Step 1, after building the example, I tested it with something "non-oracle" -- to eliminate that from the mix. I have a program "touch.exe" which when executed simply updates the timestamp on a file in the OS and if the file does not exist, it creates hence.

Hence I ran "exec shell( c:\bin\touch c:\temp\test.dat" );"

Sure enough, the file test.dat appeared -- proving the extproc itself functions.

Then I tried export -- sure enough, that DID NOT work.

Step 2, lets capture the output. In order to diagnose this (and in order to be able to verify the export actually WORKED) we need to capture the output. Using SYSTEM, the easiest way is:


tkyte@TKYTE816> host erase \temp\exp.log
tkyte@TKYTE816> begin
2 shell( 'c:\oracle\bin\exp userid=scott/tiger ' ||
3 ' file=c:\temp\test.dmp tables=emp 2> \temp\exp.log' );
4 end;
5 /

PL/SQL procedure successfully completed.


that would not only run our command but it would also redirect stderr to a file we can look at. When I ran that, I saw clearly what the issue was:


tkyte@TKYTE816> host type \temp\exp.log

Export: Release 8.1.6.0.0 - Production on Sat Nov 17 13:02:35 2001

(c) Copyright 1999 Oracle Corporation. All rights reserved.


EXP-00056: ORACLE error 12560 encountered
ORA-12560: TNS:protocol adapter error
EXP-00000: Export terminated unsuccessfully

So, it is simply not able to connect (it in fact was running exp -- you just had no way to see the output from exp and now you do). So, once we have that -- we can go the next step. Well, I would really like to see the environment cause 12560 is almost always an environment issue. At this point, I stop running exp and just run SET to see whats the environment looks like:

tkyte@TKYTE816> host erase \temp\exp.log

tkyte@TKYTE816>
tkyte@TKYTE816> begin
2 shell( 'command /c set > \temp\exp.log' );
3 end;
4 /

PL/SQL procedure successfully completed.

tkyte@TKYTE816> host type \temp\exp.log
COMSPEC=C:\WINNT\SYSTEM32\COMMAND.COM
ORACLE_SID=extproc

ALLUSERSPROFILE=C:\DOCUME~1\ALLUSE~1
COMMONPROGRAMFILES=C:\PROGRA~1\COMMON~1
COMPUTERNAME=TKYTE-DELL
JSERV=C:\oracle9i/Apache/Jserv/conf
NUMBER_OF_PROCESSORS=1
OLAP_HOME=C:\oracle9i\olap
OS=Windows_NT
OS2LIBPATH=C:\WINNT\system32\os2\dll;
PATH=C:\oracle\bin;C:\oracle9i\bin;C:\orant\bin;C:\oracle9i/bin;C:\oracle9i\Apache\Perl\
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 8 Stepping 3, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0803
PROGRAMFILES=C:\PROGRA~1
PROMPT=$P$G
SYSTEMDRIVE=C:
SYSTEMROOT=C:\WINNT
TEMP=C:\WINNT\TEMP
TMP=C:\WINNT\TEMP
USERPROFILE=C:\DOCUME~1\DEFAUL~1
WV_GATEWAY_CFG=C:\oracle9i\Apache\modplsql\cfg\wdbsvr.app

Well, there is the problem in this case -- we are using the EXTPROC service, so the ORACLE_SID is in fact "extproc".

At this point, we have a couple of choices, two of which I have below - one we can use Net8:

tkyte@TKYTE816> host erase \temp\exp.log

tkyte@TKYTE816>
tkyte@TKYTE816> begin
2 shell( 'c:\oracle\bin\exp userid=scott/tiger@tkyte816 ' ||
3 ' file=c:\temp\test.dmp tables=emp 2> \temp\exp.log' );
4 end;
5 /

PL/SQL procedure successfully completed.

tkyte@TKYTE816> host type \temp\exp.log

Export: Release 8.1.6.0.0 - Production on Sat Nov 17 13:05:36 2001

(c) Copyright 1999 Oracle Corporation. All rights reserved.


Connected to: Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production
Export done in WE8ISO8859P1 character set and WE8ISO8859P1 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table EMP 14 rows exported
Export terminated successfully without warnings.



The other is to run more than one command:

tkyte@TKYTE816> host erase \temp\exp.log

tkyte@TKYTE816>
tkyte@TKYTE816> begin
2 shell( 'set ORACLE_SID=tkyte816 && ' ||
3 'c:\oracle\bin\exp
userid=scott/tiger@tkyte816 ' ||
4 ' file=c:\temp\test.dmp tables=emp 2> \temp\exp.log' );
5 end;
6 /

PL/SQL procedure successfully completed.

tkyte@TKYTE816> host type \temp\exp.log

Export: Release 8.1.6.0.0 - Production on Sat Nov 17 13:08:45 2001

(c) Copyright 1999 Oracle Corporation. All rights reserved.


Connected to: Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production
Export done in WE8ISO8859P1 character set and WE8ISO8859P1 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table EMP 14 rows exported
Export terminated successfully without warnings.



And there you go (you can get the ORACLE_SID you need from v$instance:

tkyte@TKYTE816> select instance_name from v$instance;

INSTANCE_NAME
----------------
tkyte816

if you would like to make this generic.


Hopefully, this will show you how to debug these sorts of issues in the future. you should note that you should use UTL_FILE or a bfile to open, read and verify the success of your command! You could use dbms_lob.loadfromfile as well to get it into a database table for future reference.



Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Good techniques

Doug, November 17, 2001 - 1:57 pm UTC

These will come in handy - and it probably took you less than 10 minutes.

Ravi, April 27, 2005 - 8:59 am UTC

Tom,
Is there a way to capture the Output of Export ONLY when it fails. I've tried 2> \temp\exp.log but it records SUCCESSFUL exports, as well, which I dont need.
Thanks
Ravi

Tom Kyte
April 27, 2005 - 9:20 am UTC

in 10g, when an export can be a stored procedure (API) call -- yes, using the data pump.

Using a command line tool -- it'll be a matter of grepping log files -- and defining what you mean by "success".




Ravi, April 27, 2005 - 9:29 am UTC

B. Successful export/import with warnings.
---------------------------------------
Result : Export terminated successfully with warnings
Import terminated successfully with warnings
Exit Code : EX_OKWARN
Exit Level: 0 (for Unix platforms)
1 (for Windows platform with Oracle9i, Oracle8i, and below)
3 (for Windows platform with Oracle10g and higher)

C. Unsuccessful export/import.
---------------------------
Result : Export terminated unsuccessfully
Import terminated unsuccessfully
Exit Code : EX_FAIL
Exit Level: 1 (for Unix platforms, and for Windows platforms with
Oracle10g and higher)
3 (for Windows platform with Oracle9i, Oracle8i, and below)


CHECK
=====

To determine the errorlevel at the commandline after a command ends:

- Unix Bourne/Korn shell:
echo $?
- Unix C Shell:
echo $status
- Windows:
echo %ERRORLEVEL%

Had a closer look at help, I want to interogate the EX_OKWARN value in Unix. NOT the Error level using echo $?, as you would have guessed my Export actually fails with a Warning but returns exit code 0.

Tom Kyte
April 27, 2005 - 9:31 am UTC

<quote>as you would have guessed my Export actually
fails with a Warning</quote>

"fails with a warning"?

(i've never found the return codes to be 100% reliable...)

More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.