如何在sql server中的标量函数中传递列名

时间:2012-12-25 10:34:58

标签: sql sql-server-2008 user-defined-functions

我在sql server中创建一个标量函数。并将列名作为参数传递给函数。在这个函数中我使用那个列名与该表。此处@FromCurrency@ToCurrencyCurrencyConversion表的列名 代码如下:

alter FUNCTION fnCurrencyConversion  --1200.90,'NGN','CAD' 
      (@MoneyAmount MONEY,
       @FromCurrency nvarchar(20),
       @ToCurrency nvarchar(20))  
RETURNS decimal(18,2)  
AS  
BEGIN 
  declare @BaseToUsd nvarchar(1000), @UsdToTarget nvarchar(1000)
  declare @Rate decimal(18,5) 
  set @BaseToUsd= ('select top 1 '+ @FromCurrency  +' from CurrencyConversion order by id desc')
  set @UsdToTarget = ('select top 1 '+ @ToCurrency  +'  from CurrencyConversion order by id desc') 

  set @Rate = @UsdToTarget/@BaseToUsd
  declare @TotalAmt decimal(18,5)
  set @TotalAmt = (@Rate * @MoneyAmount)  
  return @TotalAmt 

END 

如何在sql中的标量值函数中传递列名?

1 个答案:

答案 0 :(得分:1)

UDF不支持使用动态SQL,即使它们使用了错误的语法。

你可以创建一个存储过程,按照以下方式执行此操作:

create procedure procCurrencyConversion  --1200.90,'NGN','CAD' 
      (@MoneyAmount MONEY,
       @FromCurrency nvarchar(20),
       @ToCurrency nvarchar(20))  
AS  
BEGIN 
  declare @BaseToUsd nvarchar(1000), @UsdToTarget nvarchar(1000)
  declare @Rate decimal(18,5) 
  declare @SQL nvarchar(4000)

  set @SQL = 'select top 1 @BaseToUsd ='+ @FromCurrency  +N' from CurrencyConversion order by id desc'
  exec sp_executesql @SQL, N'@BaseToUsd nvarchar(1000) output', @BaseToUsd output

  set @SQL = 'select top 1 @UsdToTarget='+ @ToCurrency  +N' from CurrencyConversion order by id desc'
  exec sp_executesql @SQL, N'@UsdToTarget nvarchar(1000) output', @UsdToTarget output

  set @Rate = @UsdToTarget/@BaseToUsd
  declare @TotalAmt decimal(18,5)
  set @TotalAmt = (@Rate * @MoneyAmount)  
  select @TotalAmt 

END 

请注意sp_executesql有一个非常简洁的语法,并不是为了佯装心脏:) 另外,我建议对CurrencyConversion表进行规范化,以便您可以在没有动态SQL的情况下获取数据,类似于Currency列并且每个货币插入一行,而不是使用单独的字段每个。
另外,尽量避免使用UDF,特别是在大型数据集上,因为它们以逐行的方式工作,并且是巨大的性能瓶颈。