如何从另一个SQL函数调用SQL函数

时间:2014-06-05 14:21:47

标签: sql sql-server

在我的数据库中,我有两种类型的应用程序:序列号和没有序列号。我想在SQL Server中创建一个函数,它将参数作为参数2 nvarchars:首先是应用程序代码,另一个是序列号,并返回包含可用版本的表类型。此函数应首先检查应用程序是否具有序列号,并根据答案(即位类型)调用正确的函数。我怎么把它放在一起?

table getVersions(appCode, serial){
  if(isFree(appCode)){
     call getAppVersionsFree(appCode); 
  } else {
     call getAppVersions(appCode,serial);
  }
return table;

检查应用程序是否有序列号或是免费的功能:

create function dbo.isFree(
   @appCode nvarchar(128))
returns bit
as 
begin
   declare @ret bit
   select @ret = (select a.IsFree from Application a where a.Code=@appCode)
   return @ret
end

如果应用程序是免费的,则调用函数:

create function dbo.getAppVersionsFree
(
   @appCode nvarchar(128))
returns table as
return (
   select v.Version from Version v 
   inner join Application a on a.Code = v.AppCode
   inner join SerialNumber s on a.Code = s.AppCode
   where a.Code = @appCode 
)

如果应用程序不是免费的(带序列号),则要调用的函数:

create function dbo.getAppVersions
(
   @appCode nvarchar(128),
   @serialNo nvarchar(128))
   returns table as
   return (
      select v.Version from Version v 
      inner join Application a on a.Code = v.AppCode
      inner join SerialNumber s on a.Code = s.AppCode
      where a.Code = @appCode and s.SerialNo = @serialNo
)

编辑:

如何使其发挥作用?

create function dbo.getVersions
(
   @appCode nvarchar(128),
   @serialNo nvarchar(128))   
returns table 
as
begin
declare @returnTable table (Version nvarchar(10))
if(dbo.isFree(@appCode) = 0) begin  
    set @returnTable = select dbo.getAppVersions(@appCode,@serialNo)
    end
else begin
   set @returnTable = select dbo.getAppVersionsFree(@appCode)
   end
return @returnTable;
end

1 个答案:

答案 0 :(得分:1)

您有两个选项(在SQL中):

第一个选项是写Multistatement Table-valued Function。语法如下(from MSDN):

--Transact-SQL Multistatement Table-valued Function Syntax
CREATE FUNCTION [ schema_name. ] function_name 
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type 
    [ = default ] [READONLY] } 
    [ ,...n ]
  ]
)
RETURNS @return_variable TABLE <table_type_definition>
    [ WITH <function_option> [ ,...n ] ]
    [ AS ]
    BEGIN 
        function_body
        RETURN
    END
[ ; ]

在这种情况下,您应该将INSERT所选记录放入声明的返回(表)变量中。 您可以在多语句函数中编写逻辑。

诀窍在于RETURN声明所在的行:

RETURNS @return_variable TABLE <table_type_definition>

在你的情况下,这将是这样的:

RETURNS @returnVersions TABLE (Version INT)

逻辑是这样的:

IF (dbo.IsFree( ... )) BEGIN
    INSERT INTO @returnVersion (Version) SELECT Version FROM dbo.GetVersionsFree( ... )
END
ELSE BEGIN
    INSERT INTO @returnVersion (Version) SELECT Version FROM dbo.GetVersions( ... )
END

第二个选项是修改你的函数来处理这两种情况:

SELECT
    v.Version
FROM
    Version v 
    INNER JOIN Application a
        ON a.Code = v.AppCode
WHERE
    a.Code = @appCode
    AND (
        -- The given application is free
        a.IsFree = 1

        -- The serial number should exist when the application is not free
        OR (
            a.IsFree = 0
            AND EXISTS (
                SELECT 1
                FROM SerialNumber s
                WHERE a.Code = s.AppCode AND s.SerialNo = @serialNo
            )
        )
    )

(请注意,我没有测试此选择语句,因此可能存在拼写错误)