仅使用一个用户定义的函数计算Select语句的多个列

时间:2014-06-30 09:31:51

标签: sql sql-server tsql

我在SQL Server中使用两个输出参数构建了一个存储过程。存储过程的唯一输入参数是表的ID。我现在要做的是构建一个表(ID,SP_Result1,SP_Result2)。

我的初始方法是创建一个Cursor over ID,遍历此Cursor,计算当前ID的存储过程,并将(@ ID,@ SP_Result1,@ SP_Result2)插入表行逐行。由于我使用的是Cursor运行时并不好。所以现在我的想法是用两个用户定义的函数替换存储的过程,这样我可以用

替换Cursor
Insert into Table
Select
ID
,udf1(ID)
,udf2(ID)
From ID_Table

然而在这种情况下,udf1和udf2计算几乎完全相同的东西,如果我只能运行一个udf但是有2个结果,就像我用我原来的存储过程那样,我可能会将运行时减少一半。

示例:ID是char(10),我当前拥有的存储过程能够 - 通过使用其他表并进行相当多的计算 - 为此ID计算2个十进制输出变量。第一个和第二个输出变量的计算仅在存储过程的最后进行,输出1和输出2的95%计算完全相同。我做的事情就像是:

create Table result
(ID char(10)
,SP_Result1 decimal(28,12)
,SP_Result2 decimal(28,12))

declare @IDIterator char(10)
declare @SPResult1 decimal(28,12)
declare @SPResult2 decimal(28,12)
declare @Cursor Cursor

Set @Cursor = Cursor for
Select ID
From ID_Table
Open @Cursor
Fetch Next From @Cursor into @IDIterator

While (@@Fetch_Status=0)

Exec dbo.StoredProcedure
@ID = @IDIterator
,@SPResult1 = @SPResult1 Output
,@SPResutl2 = @SPresult2 Output

Insert Into result
Select
@ID
,@SPResult1
,@SPResult2

Fetch next
From @Cursor into @TransIterator

END
Close @Cursor
Deallocate @Cursor

可以做的是将我的存储过程拆分为两个用户定义函数 - 第一个结果为1,第二个结果为第二个。这样我就可以避开光标:

create Table result
(ID char(10)
,SP_Result1 decimal(28,12)
,SP_Result2 decimal(28,12))

Insert into result
Select 
ID
,udf1(ID)
,udf2(ID)
From ID_Table

想要做的事情是使用带有两个输出变量的udf作为最终选择的2列,因为udf1和udf2对相同的输入ID几乎执行相同的计算。所需代码的非工作示例如下所示:

Insert into result
select
ID
,udf1(ID).Output1
,udf1(ID).Output2
From ID_table

其中udf1每行只计算一次。

以某种方式可以做到这一点吗?我已经查看了Table-Valued函数,但我无法弄清楚这些可以帮助我解决这个问题。

1 个答案:

答案 0 :(得分:2)

你可以像 -

那样创建表值函数
CREATE FUNCTION [dbo].udf(@ID  INT)
RETURNS TABLE AS RETURN
    SELECT 1 AS Output1, 2 AS Output2

GO

然后可以使用交叉应用调用函数或与表连接

SELECT
I.ID,RESULT.OUTPUT1,RESULT.OUTPUT2
FROM ID_TABLE I
CROSS APPLY DBO.UDF(I.ID) RESULT