Oracle打包函数无法通过SQL Server 2008 R2链接服务器运行

Oracle打包函数无法通过SQL Server 2008 R2链接服务器运行,oracle,plsql,sql-server-2000,linked-server,Oracle,Plsql,Sql Server 2000,Linked Server,我在oracle(10g)包中有以下重载函数 在Oracle Sql Developer中执行时,这两种方法都可以很好地工作,如下所示 select t$stdt,to_char(t$tdat,'dd-Mon-YYYY') t$tdat, t$cuno,T$CPGS,T$QANP,T$DISC from baan.ttdsls031020 where trim(t$cuno) = '000811' and pkgUtils.

我在oracle(10g)包中有以下重载函数

在Oracle Sql Developer中执行时,这两种方法都可以很好地工作,如下所示

select t$stdt,to_char(t$tdat,'dd-Mon-YYYY') t$tdat, t$cuno,T$CPGS,T$QANP,T$DISC 
   from baan.ttdsls031020 
       where 
       trim(t$cuno)        =   '000811' 
      and pkgUtils.fnDaysFromNowToDate(to_char(t$tdat,'dd-Mon-YYYY')) >  1
        and t$qanp           =   pkgPriceWorx.fndefaultQanp 
      and trim(t$cpgs)  =   '1AM00';
但当我使用OraOLEDB.Oracle提供程序通过SQL链接服务器执行相同的查询时

select * from openquery(hades,"
select t$stdt,to_char(t$tdat,'dd-Mon-YYYY') t$tdat, t$cuno,T$CPGS,T$QANP,T$DISC 
   from baan.ttdsls031020 
       where 
       trim(t$cuno)        =   '000811' 
      and pkgUtils.fnDaysFromNowToDate(to_char(t$tdat,'dd-Mon-YYYY')) >  1
        and t$qanp           =   pkgPriceWorx.fndefaultQanp 
      and trim(t$cpgs)  =   '1AM00'
       ");
将抛出以下错误

链接服务器“hades”的OLE DB提供程序“OraOLEDB.Oracle”返回消息
ORA-01861:文字与格式字符串不匹配
ORA-06512:在“SAAP.PKGUTILS”的第29行.OLEDB提供程序“OraOLEDB.Oracle”中 链接服务器“hades”返回消息“ORA-01861:文本不存在 匹配格式字符串ORA-06512:“SAAP.PKGUTILS”第29行“.Net” SqlClient数据提供程序:Msg 7320,级别16,状态2,第3行无法访问 执行查询“选择t$stdt,to_char(t$tdat,'dd-Mon-YYYY') baan的tdat、cuno、CPGS、QANP和DISC均为t$ttdsls031020 哪里 修剪(t$cuno)='000811' 和pkgUtils.fnDaysFromNowToDate(to_char(t$tdat,'dd-Mon-YYYY'))>1 和t$qanp=pkgPriceWorx.fndefaultQanp 和修剪(t$cpgs)='1AM00' 针对链接服务器“hades”的OLE DB提供程序“OraOLEDB.Oracle”*


知道为什么会出现这种行为吗?

我不认为重载接收日期的plsql函数和接收varchar2的plsql函数是一种好的做法,因为oracle多次根据NLS_Date_格式自动将varchar2转换为Date,这种格式可能因环境而异

无论如何,如果t$tdat是varchar2,您不应该运行“to_char(t$tdat,'dd-Mon-YYYY')”,因为oracle将根据NLS_date格式首先将您的varchar2转换为一个日期(因为to_char获取一个日期作为参数)。
您也不应使用日期来确定日期(来自同一原因)

如果您想对不知道是否获得varchar2或日期的情况使用重载,可以这样做:

function do_things(d date) return number is

begin

dbms_output.put_line('d=' || to_char(d, 'dd-mon-yyyy'));
dbms_output.put_line('s=' || to_char(sysdate, 'dd-mon-yyyy'));

return trunc(d - trunc(sysdate));

end do_things;


function fnDaysFromNowToDate(dd_mon_yyyy date) return number is
days number;
begin
--d2 varchar2(11):=to_char(sysdate,ddf);Begin dbms_output.put_line( 'd='|| to_date(dd_mon_yyyy,'dd-mon-yyyy'));

dbms_output.put_line('function gets date');
days := do_things(dd_mon_yyyy);
return days;

end fnDaysFromNowToDate;
--return 1; end; --- overload for varchar


function fnDaysFromNowToDate(dd_mon_yyyy varchar2) return number is
days number;
Begin
dbms_output.put_line('function gets varchar2');
days := do_things(to_date(dd_mon_yyyy, 'dd-mon-yyyy'));
return days;

end fnDaysFromNowToDate;

在我的例子中,我需要使用trunc(sysdate)

我需要从SQL Server 2005链接服务器调用oracle函数。我已经创建了链接服务器,可以查询它,但在调用oracle函数时,我遇到了不同的错误,如 链接服务器“BAN23”的OLE DB提供程序“OraOLEDB.Oracle”返回消息“ORA-01841:(完整)年份必须介于-4713和+9999之间,而不是0”

链接服务器“BAN23”的OLE DB提供程序“OraOLEDB.Oracle”返回消息“ORA-01861:文本与格式字符串不匹配”

我尝试了不同的查询,比如 从openquery中选择*(BAN23,从dual中选择contab.fu\u icaro\u tasas(“当前日期”,“美元”,“COP”))

从openquery中选择*(BAN23,从dual中选择contab.fu\U icaro\U tasas(“系统日期”,“美元”,“COP”)

从openquery中选择*(BAN23,“从dual中选择contab.fu\u icaro\u tasas(截止日期(当前日期,'DD-MM-YYYY'),'USD','COP')) 从openquery中选择*(BAN23,“从dual中选择contab.fu\u icaro\u tasas(到日期(系统日期,'DD-MM-YYYY'),'USD','COP'))

我的解决方案是添加trunc(sysdate)或trunc(current_date)

从openquery中选择*(BAN23,“从dual中选择contab.fu\u icaro\u tasas(trunc(当前日期),“USD”,“COP”)


最后一个查询运行得很好。

第29行的“SAAP.PKGUTILS”中有什么?接收日期的是日期类型的t$tdat吗?它可以是varchar2或date类型,重载应该启动并确定调用这两个类型中的哪一个,在本例中它是char(varchar2)类型它在oracle sql developer中工作,但与链接服务器无关。
function do_things(d date) return number is

begin

dbms_output.put_line('d=' || to_char(d, 'dd-mon-yyyy'));
dbms_output.put_line('s=' || to_char(sysdate, 'dd-mon-yyyy'));

return trunc(d - trunc(sysdate));

end do_things;


function fnDaysFromNowToDate(dd_mon_yyyy date) return number is
days number;
begin
--d2 varchar2(11):=to_char(sysdate,ddf);Begin dbms_output.put_line( 'd='|| to_date(dd_mon_yyyy,'dd-mon-yyyy'));

dbms_output.put_line('function gets date');
days := do_things(dd_mon_yyyy);
return days;

end fnDaysFromNowToDate;
--return 1; end; --- overload for varchar


function fnDaysFromNowToDate(dd_mon_yyyy varchar2) return number is
days number;
Begin
dbms_output.put_line('function gets varchar2');
days := do_things(to_date(dd_mon_yyyy, 'dd-mon-yyyy'));
return days;

end fnDaysFromNowToDate;