如何在sql server中的标量函数中传递列名[关闭]

Posted

技术标签:

【中文标题】如何在sql server中的标量函数中传递列名[关闭]【英文标题】:How to pass column name in scalar function in sql server [closed] 【发布时间】:2012-12-25 10:34:58 【问题描述】:

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

【问题讨论】:

UDF 不支持使用动态 SQL,即使他们使用了错误的语法。 【参考方案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,尤其是在大型数据集上,因为它们以逐行痛苦的方式工作,并且是巨大的性能瓶颈。

【讨论】:

您认为当前的CurrencyConversion 表打破了什么规范化规则? 1NF?它不是与phone1,phone2 IMO 相同的重复组,因为这些列代表不同的货币,而不是同一事物的多个实例。 @MartinSmith 是的,它是一个重复组(1 列),是的,它们是“货币价值”事物的多个实例。这更像是“verizon-phone”、“tmobile-phone”、“att-phone”的情况,但还是一样的。 所以如果一个表有列startDateendDate 你还会说它有多个“日期值”的实例吗? - 对重构没有争议,因此添加新货币不涉及添加列可能不是一个坏主意,但不确定it breaks 1NF @MartinSmith:不,这些是严格定义的,新的midDate 似乎不太可能。 startDateendDate 也可以有不同的用法和规则(即start 不为空,end 为空)。另一方面,货币都有相同的规则和计算可供它们使用。 我得再考虑一遍!

以上是关于如何在sql server中的标量函数中传递列名[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MS Access VB 中访问 SQL Server 标量函数

我应该如何使用 sql server 中的存储过程将列名存储在变量中?

Sql Server 中的标量最大值

SQL Server如何定位自定义标量函数被那个SQL调用次数最多浅析

SQL Server标量函数将数字转换为带有序数的单词

SQL Server如何定位自定义标量函数被那个SQL调用次数最多浅析