oracle中execute函数,TO_DATE问题与Oracle DBMS_SQL.EXECUTE函数

你所说的似乎有一个矛盾,但流程并不十分清楚。你有一个从函数(未命名)调用的过程(P_USER_TIME?)。你的程序(至少看看它是如何声明的)将采用字符串参数,但是你传递的是date,而不是varchar2值。由于我们没有您的实际程序,让我们提出一个:

create or replace procedure p_user_time(p_time varchar2) is

l_time date;

begin

dbms_output.put_line('Parameter p_time: ' || p_time);

l_time := to_date(p_time, 'DD-MON-YYYY HH24:MI:SS');

dbms_output.put_line('Converted l_time: ' ||

to_char(l_time, 'DD-MON-YYYY HH24:MI:SS'));

end;

/如果我用你传递给plsql_block的字符串调用它,我得到:

alter session set nls_date_format = 'DD-MON-YYYY';

set serveroutput on

exec P_USER_TIME(to_date('21-JUL-2012 03:30:30','DD-MON-YYYY HH24:MI:SS'));

Session altered.

Parameter p_time: 21-JUL-2012

Converted l_time: 21-JUL-2012 00:00:00

PL/SQL procedure successfully completed.所以时间部分丢失了。您正在将表示日期的字符串转换为date对象,当它传递给过程时,它会使用您的默认NLS_DATE_FORMAT掩码隐式转换回字符串,我猜这可能是DD-MON-YYYY;所以这相当于:

exec P_USER_TIME(to_char(to_date('21-JUL-2012 03:30:30','DD-MON-YYYY HH24:MI:SS')));做to_char(to_date(...))看起来是多余的,但是因为你有一个明确的数据掩码,另一个是隐式数据掩码,它可能没有达到预期的效果。

假设P_USER_TIME过程期望您传递的特定格式的日期/时间字符串,您应该只传递字符串,而不是尝试自己转换它:

exec P_USER_TIME('21-JUL-2012 03:30:30');

Parameter p_time: 21-JUL-2012 03:30:30

Converted l_time: 21-JUL-2012 03:30:30

PL/SQL procedure successfully completed.您还有一个动态调用过程的函数。再一次,让我们做一个:

create or replace function f_foo return number is

ln_dbms_cur number;

ret_int number;

plsql_block varchar2(256);

begin

plsql_block := 'BEGIN P_USER_TIME(to_date(''21-JUL-2012 03:30:30'',''DD-MON-YYYY HH24:MI:SS'')); END;';

ln_dbms_cur := DBMS_SQL.OPEN_CURSOR;

DBMS_SQL.PARSE(ln_dbms_cur, plsql_block, DBMS_SQL.NATIVE);

ret_int := DBMS_SQL.EXECUTE(ln_dbms_cur);

DBMS_SQL.CLOSE_CURSOR(ln_dbms_cur);

return ret_int;

end;

/

var rc number;

exec :rc := f_foo;

Parameter p_time: 21-JUL-2012

Converted l_time: 21-JUL-2012 00:00:00

PL/SQL procedure successfully completed.所以同样的事情发生了。如果plsql_block的构造简化为:

plsql_block := 'BEGIN P_USER_TIME(''21-JUL-2012 03:30:30''); END;';然后你得到:

Parameter p_time: 21-JUL-2012 03:30:30

Converted l_time: 21-JUL-2012 03:30:30

PL/SQL procedure successfully completed.

再次阅读这个问题,实际上可能是一个更简单的潜在问题。

你说'...字符串参数,我使用to_date函数以字符串格式传递当前日期'。

如果按字面意思解释,那么当你应该有to_char时,它表明你可能只是在使用to_date;

如果你真的想要当前时间会使函数中的行像:

plsql_block := 'BEGIN P_USER_TIME(to_char(sysdate, ''DD-MON-YYYY HH24:MI:SS'')); END;';或者使用直接调用程序:

exec P_USER_TIME(to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS'));

Parameter p_time: 31-JUL-2012 09:38:43

Converted l_time: 31-JUL-2012 09:38:43

PL/SQL procedure successfully completed.

编辑以查看作为评论发布的Java代码

你的函数现在似乎有两个参数,其中一个是你想要执行的块;并返回一个游标。我将(再次)猜测光标正在返回已插入的内容,因此我更改了我的虚拟过程以将日期/时间插入到表中,并且我的函数用于检索它。如果您发布了一组完整的代码来演示您所看到的问题,那么这将会容易得多。

create or replace procedure p_user_time(p_time varchar2) is

l_time date;

begin

dbms_output.put_line('Parameter p_time: ' || p_time);

l_time := to_date(p_time, 'DD-MON-YYYY HH24:MI:SS');

dbms_output.put_line('Converted l_time: ' ||

to_char(l_time, 'DD-MON-YYYY HH24:MI:SS'));

insert into cooldude values(l_time);

end;

/

create or replace function f_foo(pNumber number, p_plsql_block in varchar2)

return sys_refcursor is

ln_dbms_cur number;

ret_int number;

plsql_block varchar2(256);

rc sys_refcursor;

begin

ln_dbms_cur := DBMS_SQL.OPEN_CURSOR;

DBMS_SQL.PARSE(ln_dbms_cur, p_plsql_block, DBMS_SQL.NATIVE);

ret_int := DBMS_SQL.EXECUTE(ln_dbms_cur);

DBMS_SQL.CLOSE_CURSOR(ln_dbms_cur);

open rc for select * from cooldude;

return rc;

end;

/我仍然可以从SQL * Plus中调用它,没有任何问题。我可以让Java程序执行它:

import java.sql.*;

import java.text.*;

import oracle.jdbc.*;

import oracle.jdbc.pool.OracleDataSource;

public class Cooldude

{

public static void main(String args[]) throws SQLException

{

String plSqlBlk = "BEGIN P_USER_TIME(to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS')); END;";

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Connection conn;

OracleDataSource ds = new OracleDataSource();

ds.setURL("jdbc:oracle:thin:scott/oracle@127.0.0.1:1521:orcl");

conn = ds.getConnection();

CallableStatement cstmt = null;

ResultSet rs = null;

String output = "";

System.out.println("******calling SP *******");

cstmt = conn.prepareCall("{? = call f_foo(?,?)}");

cstmt.setFetchSize(10000);

cstmt.registerOutParameter(1, OracleTypes.CURSOR);

cstmt.setInt(2, 204149885);

cstmt.setString(3, plSqlBlk);

cstmt.executeQuery();

rs = (ResultSet) cstmt.getObject(1);

while (rs.next())

{

Timestamp ts = rs.getTimestamp(1);

System.out.println(sdf.format(ts));

}

if ( conn != null )

{

try { conn.close(); } catch ( Exception ex ) {}

conn = null;

}

}

}

javac Cooldude.java && java Cooldude

******calling SP *******

2012-08-11 09:45:07

2012-08-11 09:46:04

2012-08-11 09:54:33这看起来很好;这有三次调用Java程序的输出。

您还没有说出为什么您认为Java代码中的时间被截断的原因。我会更进一步......你是把它放在你的Java显示器上,显示为00:00:00;如果是这样,您使用的是rs.getDate()而不是rs.getTimestamp吗?与java.util.Date不同,java.sql.Date没有时间部分。 (例如,参见this question)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值