我想创建一个返回表的函数,根据@Parameter从不同的同义词中获取行

时间:2011-09-15 18:55:17

标签: sql-server sql-server-2005 tsql

假设我有3个同义词

  • snTable1
  • snTable2
  • snTable3

我想创建一个函数来根据传递的参数

获取行
fxFromTable (@FromDate, @ToDate, 'snTable1')  
  will return table from "Select * from snTable1 (@FromDate, @ToDate)" 

fxFromTable (@FromDate, @ToDate, 'snTable2')  
  will return table from "Select * from snTable2 (@FromDate, @ToDate)" 

fxFromTable (@FromDate, @ToDate, 'snTable3')  
  will return table from "Select * from snTable3 (@FromDate, @ToDate)" 

2 个答案:

答案 0 :(得分:0)

我想这可以通过执行动态sql来完成。但是,它不能在函数内部使用。因此,在这种情况下可以使用存储过程。这可以通过以下方式完成。

  CREATE PROCEDURE TEST
  (
       @TableName VARCHAR(50),
       @FromDate  DATETIME,
       @ToDate    DATETIME
  )
  AS
  BEGIN
       EXEC('SELECT * FROM ' + @TableName + ' WHERE FromDate = '''+ @FromDate + ''' AND ToDate = ''' + @ToDate + ''')
  END

如果要在其他存储过程中使用它,可以执行以下操作:

 INSERT @temp EXECUTE TEST

现在,@ temp可以用作普通临时表。

希望这会有所帮助!!

答案 1 :(得分:0)

您可以使用UNION ALL创建内联TVF。最后一个参数表示源类型(1 = Sales.SalesOrderHeader,2 = Sales.SpecialOffer,3 = HumanResources.Employee)。

CREATE FUNCTION dbo.GetData( @From DATETIME, @To DATETIME, @Source TINYINT )
RETURNS TABLE
AS
RETURN
SELECT  @Source AS [Source], soh.SalesOrderID BusinessObjectID, soh.OrderDate AS [Date], soh.SalesOrderNumber AS [Descriptor]
FROM    Sales.SalesOrderHeader soh
WHERE   @Source = 1
AND     soh.OrderDate BETWEEN @From AND @To
UNION ALL
SELECT  @Source , so.SpecialOfferID, so.StartDate, so.[Description]
FROM    Sales.SpecialOffer so
WHERE   @Source = 2
AND     so.StartDate >= @From 
AND     so.EndDate <= @To
UNION ALL
SELECT  @Source , e.BusinessEntityID, e.HireDate, e.NationalIDNumber
FROM    HumanResources.Employee e
WHERE   @Source = 3
AND     e.HireDate BETWEEN @From AND @To;
GO

用法:

SELECT  *
FROM    dbo.GetData('20030101', '20031231', 3);

如果查看执行计划,您会看到一些不错的东西:SQL Server只执行一个SELECT语句,而不是执行3个SELECT语句,在这种情况下只执行最后一个SELECT:

StmtText
  |--Compute Scalar(DEFINE:([Union1007]=[AdventureWorks2008].[HumanResources].[Employee].[BusinessEntityID] as [e].[BusinessEntityID], [Union1008]=CONVERT_IMPLICIT(datetime,[AdventureWorks2008].[HumanResources].[Employee].[HireDate] as [e].[HireDate],0), [Union1009]=[AdventureWorks2008].[HumanResources].[Employee].[NationalIDNumber] as [e].[NationalIDNumber]))
       |--Clustered Index Scan(OBJECT:([AdventureWorks2008].[HumanResources].[Employee].[PK_Employee_BusinessEntityID] AS [e]), WHERE:([AdventureWorks2008].[HumanResources].[Employee].[HireDate] as [e].[HireDate]>='2003-01-01 00:00:00.000' AND [AdventureWorks2008].[HumanResources].[Employee].[HireDate] as [e].[HireDate]<='2003-12-31 00:00:00.000'))

此示例基于AdventureWorks2008数据库。