你所说的似乎有一个矛盾,但流程并不十分清楚。你有一个从函数(未命名)调用的过程(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)。