-2

私はSQLサーバーでスカラー関数を作成しています。関数のパラメーターとして列名を渡します。この関数では、そのテーブルでそれらの列名を使用しています。@FromCurrencyとはテーブル@ToCurrencyの列名ですCurrencyConversion
次のようにコードします。

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はかなり簡潔な構文を持っていることに注意してください:)
さらに、テーブルを正規化して、列の行に沿って1 つの行を挿入するCurrencyConversion動的 SQL なしでデータを取得できるようにすることをお勧めしますCurrencyそれぞれに別のフィールドを使用するのではなく、通貨ごとに。
また、特に大規模なデータセットでは、UDF は行単位で動作し、パフォーマンスの大きなボトルネックとなるため、できる限り UDF を使用しないようにしてください。

于 2012-12-25T10:52:06.547 に答える