MS SQL:使用链接的Oracle服务器中的参数调用函数

时间:2017-07-24 16:07:14

标签: sql-server oracle rpc

我有MS SQL Server。它上面有一个名为HOST4KS的链接ORACLE服务器。 在Oracle DB中,我有两个功能 - 一个无参数,一个带参数。 我需要在tsql查询中获得结果。

1)没有参数的功能

RetVal:=KSOL.routines.Tst;

它总是返回int = 123

DECLARE @Resultint
select top 1 @Result= TST from openquery
(HOST4KS, 'SELECT KSOL.routines.Tst from dual') 
select @Result

好的,我在变量@Result

中得到'123'

2)带参数的功能

RetVal:=KSOL.routines.Tst2(456);

它将始终返回传递的参数。

DECLARE @Result int
select @Result = TST from openquery
(HOST4KS, 'SELECT KSOL.routines.Tst2(455) from dual') 
select @Result

工作正常。我得到@ Result = 455

问题: 如何通过参数来获得这些功能并获得可变的结果?

我试过了:

1)

DECLARE @ReturnValue int
DECLARE @InputPara int
DECLARE @OutputPara int
set @InputPara = 456
EXECUTE ( 'BEGIN ? := KSOL.routines.Tst2(?); END;', @ReturnValue, @InputPara, @OutputPara OUTPUT) AT HOST4KS

结果:链接服务器“HOST4KS”的 OLE DB提供程序“OraOLEDB.Oracle”返回消息“系统无法在OraOLEDB的消息文件中找到消息号0x80040e21的消息文本。”。 消息7215,第17级,状态1,第86行 无法在远程服务器'HOST4KS'上执行语句。

2)

DECLARE @ReturnValue int
DECLARE @InputPara int
DECLARE @OutputPara int
set @InputPara = 456
EXECUTE ( 'BEGIN ? := KSOL.routines.Tst2(?); END;', @ReturnValue, @InputPara) AT HOST4KS

结果: OLE DB提供程序“OraOLEDB.Oracle”链接服务器“HOST4KS”返回消息“ORA-06502:PL / SQL:数字或值错误 ORA-06512:第1行“。 消息7215,第17级,状态1,第92行 无法在远程服务器'HOST4KS'上执行语句。

3)

DECLARE @RetVal int
declare @Parameter int
exec HOST4KS.[defaul].dbo.sp_executesql N'SELECT KSOL.routines.Tst2(@Parameter)',N'@Parameter=10',@Parameter=10

结果:链接服务器“HOST4KS”的OLE DB提供程序“OraOLEDB.Oracle”返回消息“未指定的错误”。 Msg 7323,Level 16,State 2,Line 111 将查询文本提交到OLE DB提供程序“OraOLEDB.Oracle”时,链接服务器“HOST4KS”发生错误。

等等。没有运气......

1 个答案:

答案 0 :(得分:2)

我已经能够发现,SQL Server不允许你直接调用远程函数,你必须使用openquery。 Openquery不允许字符串是变量,也不允许字符串具有参数。我有类似的问题,但我正在调用另一个SQL Server的函数。 Oracle的答案几乎完全相同:

关于Oracle:

CREATE OR REPLACE PACKAGE testuser.routines
AS
    FUNCTION tst
        RETURN INTEGER;

    FUNCTION tst2 (p_arg IN INTEGER)
        RETURN INTEGER;
END routines;

CREATE OR REPLACE PACKAGE BODY testuser.routines
AS
    FUNCTION tst
        RETURN INTEGER
    AS
    BEGIN
        RETURN 123;
    END tst;

    FUNCTION tst2 (p_arg IN INTEGER)
        RETURN INTEGER
    AS
    BEGIN
        RETURN p_arg;
    END tst2;
END routines;

grant execute on testuser.routines to public;

SQL Server调用(CIST是我链接到Oracle数据库的服务器)

create table #tempTable (TST int);
declare @value integer = 455;
declare @cmd nvarchar(2000);
declare @result integer;
set @cmd = 'insert into #tempTable(TST) select TST from openquery
(CIST, ''SELECT TESTUSER.routines.Tst2(' + cast(@value as varchar(20)) + ') as TST from dual'') ';


exec (@cmd);
select * from #tempTable;
drop table #tempTable;
go

执行此操作成功返回455。