如何创建一个在SuperKey,SubTable数据库中返回完整行的UDF

时间:2011-12-28 19:12:12

标签: sql sql-server sql-server-2008 sql-server-2005

我想知道一个示例,该示例显示如何创建UDF或存储过程,从SQL Server数据库中的超级键/子表返回完整行(最好是2005年,但2008年就可以了)。

具体来说,让我们假设主表名为SecurityMaster,其SecurityID PK。让我们想象最后一列是SecurityType,它定义了更详细信息所在的表。让我们想象一下SecurityMaster表如下:

SecurityID  Name          Currency   SecurityType
----------  -----------   --------   ------------
1           BP Plc        GBP        Equity
2           MSFT C30 12   USD        EquityOption
3           Greek 6% 20   EUR        Bond

让我们进一步想象EquityOption表如下所示

SecurityID   PutCall   Strike   Maturity
----------   -------   ------   --------
2            Call      30       Jun 2012

让我们假设Bond表如下所示:

SecurityID   Coupon   Maturity
----------   ------   -----------
3            0.06     15 Mar 2020

我想要一个返回以下连接表的'方法'(可以是Proc或UDF):

SELECT * FROM MyFuncOrProc(2)

产生如下输出:

SecurityID  Name          Currency   SecurityType   SecurityID   PutCall   Strike   Maturity
----------  -----------   --------   ------------   ----------   -------   ------   --------
2           MSFT C30 12   USD        EquityOption   2            Call      30       Jun 2012

这里的想法是我想

  1. 避免使用超大SecurityMaster稀疏表(想象50种安全类型)
  2. 拥有需要较少存储空间的数据的紧凑表示
  3. 子表中的FK是级联更新和删除强制参照完整性
  4. 我可以提供传递给Execute命令的动态SQL字符串,但我不知道如何使返回的行可用于调用者。想象一下,您想使用结果集来执行另一个连接吗?
  5. 如果子表不存在(在Equity的情况下),则表示安全性完全由SecurityMaster
  6. 指定

    P.S。在完整示例或对示例的引用可用之前,请不要关闭此问题。

    p.p.s有人提到这可能可以使用一些sys表或列来完成,但对我来说这不是很明显,所以问题就在这里。

    非常感谢提前和亲切的问候,

    贝尔蒂。

3 个答案:

答案 0 :(得分:0)

只要表的数量有限,您就可以join将它们放在一起:

select  *
from    SecurityMaster sm
left join
        EquityOption eo
on      sm.SecurityType = 'EquityOption'
        and sm.SecurityID = eo.SecurityID
left join
        Bond b
on      sm.SecurityType = 'Bond'
        and sm.SecurityID = b.SecurityID

SecurityType列完全被省略并不罕见。如果SecurityID表中存在Bond,则可以判断证券是否为债券。

答案 1 :(得分:0)

创建简单的类似开关的proc,就像一个例子。

Create proc getFullSecurity
 @SecurityId int
As
Begin
Declare @secType nvarchar(128)

 select @secType =SecurityType
 From securitymaster 
 Where securityid=@securityid

If @sectype = 'equity'
Select join with equity table
Else if @sectype = 'something'
Select join with something
...
End

您可以在第一个查询中将所有需要的字段预取到变量中 - 然后您不需要在每个下一个选择stms时与主表连接。只使用预取变量。

答案 2 :(得分:0)

CREATE FUNCTION My_Function (@SecurityID Int)
RETURNS TABLE 
AS
RETURN 
(
          select  * 
          from SecurityMaster A
          left join EquityOption B on A.SecurityType = N'EquityOption' and B.SecurityID = A.SecurityID
          left join Bond C on A.SecurityType = N'Bond' and C.SecurityID = A.SecurityID 
          Where A.SecurityID = @SecurityID
)
GO