我使用PostgreSQL作为SQL Server的链接服务器。现在,我需要调用PostgreSQL函数,它只返回一个整数(标量),但SQL Server不允许远程表值函数,并说这个查询是一个表值函数。
CREATE OR REPLACE FUNCTION public.getpointinfo(
IN lng double precision,
IN lat double precision)
RETURNS integer
AS
$$
DECLARE result integer;
begin
result:= case when cwt.k like 'maxspeed' then cast(cwt.v as integer)
else getmaxspeed(s.highway)
end maxspeed
from snapPointToLine(ST_SetSRID(ST_MakePoint($1, $2), 4326)) s
join current_way_tags cwt
on s.id = cwt.way_id
where cwt.k in ('maxspeed', 'highway')
order by cwt.k desc
limit 1;
return result;
end
$$
LANGUAGE plpgsql VOLATILE;
如何修改此PostgreSQL查询以返回标量值,或者能够将其用作SQL Server的四部分名称函数,如
select objectid, s.data_source
from testData
outer apply
(
select maxspeed from MB24DB.MobTrack24DB.[public].getpointinfo(X, Y)
) s
openquery
不是一种选择。
答案 0 :(得分:0)
我之前做过类似的事情。您可以使用三种基本技巧。
First Trick:xp_cmdshell
您可以从UDF中调用xp_cmdshell
。因此,诀窍是让xp_cmdshell
调用sqlcmd
(或osql
)将结果放入表中,然后您可以从表中选择它们。您可以使用自己的SPID键入结果。
use tempdb
go
create table Results(
scope varchar(20) primary key,
result integer
)
go
create function dbo.test(@x integer, @y integer)
returns integer
as
begin
declare @sql nvarchar(max)
declare @scope varchar(20) set @scope = 'dbo.test@' + cast(@@spid as varchar(36))
set @sql = 'delete tempdb.dbo.Results where spid = '+@scope + '; '
set @sql = 'insert tempdb.dbo.Results select '+@scope+', '+cast(@x as nvarchar(max))+' * '+cast(@y as nvarchar(max))+' as r; '
declare @cmd varchar(max)
set @cmd = 'sqlcmd -E -Q "' + @sql +'"'
set @cmd = 'CMD /S /C "' + @cmd + ' 2>&1"'
exec xp_cmdshell @sql, NO_OUTPUT
declare @r integer
select @r = result from tempdb.dbo.results where scope = @scope
return @r
end
或者,您也可以从UDF使用insert/exec
对表变量执行xp_cmdshell
,然后解析输出数据。
declare @CMD nvarchar(max)
set @CMD = 'echo.Hello World!'
set @CMD = 'CMD /S/C "' + @cmd + ' 2>&1"'
declare @results table (ix int identity primary key, txt nvarchar(max)
declare @exitcode int
insert @results(txt)
exec @exitcode = xp_cmdshell @commandtext
-- You now have the results of your command.
第二招(sp_OACreate
您可以使用UDF中的sp_OACreate。这意味着您可以创建一个ADO连接回到您自己的数据库并执行您希望的任意操作,包括将结果放在表中以供参考。 sp_OACreate
使用起来很痛苦,所以我会留下您的文档以获取详细信息。
第三招:SQLCLR
您可以使用CLR函数解决所有这些限制,该函数可以直接连接到您的postgres数据库并执行您想要的任何操作。