我有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”发生错误。
等等。没有运气......
答案 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。