问题描述
有人可以帮助我让我知道如何在Perl脚本中调用oracle子例程
我在oracle db中已经存在一个过程。在下面说
// open the database
_initDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path,databaseName);
//try get sqlite DB file from fireBase
final File tempFile = File(path);
if (tempFile.existsSync()) {
print('App.db already existed -- Need Merge');
await tempFile.delete();
} else {
print('Try to download from Firebase');
try {
final StorageFileDownloadTask task =
storageReference.writetoFile(tempFile);
await tempFile.create();
final int byteCount = (await task.future).totalByteCount;
print('total download size $byteCount');
} catch (error) {
print(error);
}
}
return await openDatabase(
path,version: databaseVersion,onCreate: _onCreate,);
然后在sql开发人员中,我可以直接执行它:
CREATE OR REPLACE PROCEDURE procCursorExample(
cursorParam OUT SYS_REFCURSOR,userNameParam IN VARCHAR2)
IS
BEGIN
OPEN cursorParam FOR
SELECT * FROM DBUSER WHERE USERNAME = userNameParam;
END;
有人可以告诉我如何通过Perl脚本调用带有参数的子例程
答案
DECLARE
dbUserCursor SYS_REFCURSOR;
dbUserTable DBUSER%rOWTYPE;
BEGIN
procCursorExample(dbUserCursor,'mkyong');
LOOP
FETCH dbUserCursor INTO dbUserTable;
EXIT WHEN dbUserCursor%NOTFOUND;
dbms_output.put_line(dbUserTable.user_id);
END LOOP;
CLOSE dbUserCursor;
END;
我不确定准备语句。任何帮助都是非常重要的。
解决方法
请阅读用于使用DBD::Oracle(这是您使用的驱动程序)在Perl中调用存储过程的文档示例。
use DBI;
my($db,$csr,$ret_val);
$db = DBI->connect('dbi:Oracle:database','user','password')
or die "Unable to connect: $DBI::errstr";
# So we don't have to check every DBI call we set RaiseError.
# See the DBI docs now if you're not familiar with RaiseError.
$db->{RaiseError} = 1;
# Example 1 Eric Bartley <bartley@cc.purdue.edu>
#
# Calling a PLSQL procedure that takes no parameters. This shows you the
# basic's of what you need to execute a PLSQL procedure. Just wrap your
# procedure call in a BEGIN END; block just like you'd do in SQL*Plus.
#
# p.s. If you've used SQL*Plus's exec command all it does is wrap the
# command in a BEGIN END; block for you.
$csr = $db->prepare(q{
BEGIN
PLSQL_EXAMPLE.PROC_NP;
END;
});
$csr->execute;
# Example 2 Eric Bartley <bartley@cc.purdue.edu>
#
# Now we call a procedure that has 1 IN parameter. Here we use bind_param
# to bind out parameter to the prepared statement just like you might
# do for an INSERT,UPDATE,DELETE,or SELECT statement.
#
# I could have used positional placeholders (e.g. :1,:2,etc.) or
# ODBC style placeholders (e.g. ?),but I prefer Oracle's named
# placeholders (but few DBI drivers support them so they're not portable).
my $err_code = -20001;
$csr = $db->prepare(q{
BEGIN
PLSQL_EXAMPLE.PROC_IN(:err_code);
END;
});
$csr->bind_param(":err_code",$err_code);
# PROC_IN will RAISE_APPLICATION_ERROR which will cause the execute to 'fail'.
# Because we set RaiseError,the DBI will croak (die) so we catch that with eval.
eval {
$csr->execute;
};
print 'After proc_in: $@=',"'$@',errstr=$DBI::errstr,ret_val=$ret_val\n";
# Example 3 Eric Bartley <bartley@cc.purdue.edu>
#
# Building on the last example,I've added 1 IN OUT parameter. We still
# use a placeholders in the call to prepare,the difference is that
# we now call bind_param_inout to bind the value to the place holder.
#
# Note that the third parameter to bind_param_inout is the maximum size
# of the variable. You normally make this slightly larger than necessary.
# But note that the Perl variable will have that much memory assigned to
# it even if the actual value returned is shorter.
my $test_num = 5;
my $is_odd;
$csr = $db->prepare(q{
BEGIN
PLSQL_EXAMPLE.PROC_IN_INOUT(:test_num,:is_odd);
END;
});
# The value of $test_num is _copied_ here
$csr->bind_param(":test_num",$test_num);
$csr->bind_param_inout(":is_odd",\$is_odd,1);
# The execute will automagically update the value of $is_odd
$csr->execute;
print "$test_num is ",($is_odd) ? "odd - ok" : "even - error!","\n";
# Example 4 Eric Bartley <bartley@cc.purdue.edu>
#
# What about the return value of a PLSQL function? Well treat it the same
# as you would a call to a function from SQL*Plus. We add a placeholder
# for the return value and bind it with a call to bind_param_inout so
# we can access its value after execute.
my $whoami = "";
$csr = $db->prepare(q{
BEGIN
:whoami := PLSQL_EXAMPLE.FUNC_NP;
END;
});
$csr->bind_param_inout(":whoami",\$whoami,20);
$csr->execute;
print "Your database user name is $whoami\n";
$db->disconnect;