MS SQL: 从链接的 Oracle 服务器调用带有参数的函数

MS SQL: Call function with parameter from linked Oracle server

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


1) 没有参数的函数

RetVal:=KSOL.routines.Tst;

它总是returnes 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);

它总是return传递参数作为结果。

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" returned 消息 "The system cannot find message text for message number 0x80040e21 in the message file for OraOLEDB."。 消息 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" returned 消息“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" returned 消息 "Unspecified error"。 消息 7323,级别 16,状态 2,第 111 行 将查询文本提交给链接服务器 "HOST4KS" 的 OLE DB 提供程序 "OraOLEDB.Oracle" 时出错。

等等。运气不好...

据我所知,SQL 服务器不允许您直接调用远程函数,您必须使用openquery。 Openquery不允许字符串是变量,也不允许字符串有参数。我有一个类似的问题,但我正在对另一个 SQL 服务器进行函数调用。 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服务器调用(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

执行成功returns 455.