-2

我正在 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中的标量值函数中传递列名?

4

1 回答 1

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,尤其是在大型数据集上,因为它们以逐行痛苦的方式工作,并且是巨大的性能瓶颈。

于 2012-12-25T10:52:06.547 回答