【问题标题】:UDF Table UDV or Scalar UDF?UDF 表 UDV 还是标量 UDF?
【发布时间】:2011-12-12 00:09:26
【问题描述】:

我会尽我最大的努力使这个问题比我上次的惨败更好。我得到了可怕的>“找不到列“dbo”或用户定义的函数或聚合“dbo.PriMonthAvgPrice”,或者名称不明确。

我正在尝试查找上个月的平均销售价格。这是我的 UDF:

USE [WoodProduction]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[PriMonthAvgPrice]
(
-- Add the parameters for the function here
@endofmonth     datetime,
@begofmonth     datetime,
@PlantCode      varchar
)
RETURNS decimal (10,2)
AS
BEGIN
-- Declare the return variable here
DECLARE @MonthEndAvgPrice  decimal (10,2)

-- Add the T-SQL statements to compute the return value here
SELECT @MonthEndAvgPrice =

(
    select  

        sum(Actual_Sales_Dollars/Actual_Volume)

        FROM

        woodproduction.dbo.plywood_layup_sales pls
        WHERE

        Production_Date between @begofmonth and @endofmonth
        and actual_volume <> 0
        and @PlantCode = pls.Plant_Code


)

-- Return the result of the function
RETURN @MonthEndAvgPrice

END

这是我的查询中的 SELECT 语句:

    SELECT
DISTINCT    
    P.[Plant_Number]
    ,p.plant_name   
,pls.plant_code
    ,(pls.[Budget_Realization]) AS 'BR'
    ,(pls.[Actual_Volume] ) AS 'AV'
    ,(pls.[Budget_Volume])  AS 'BV'
--,sum (dpb.[Gross_Production_Per_Hr]) AS 'GPB'
    ,(p.Production_Volume) AS 'PV'
    ,CASE 
        WHEN    coalesce (pls.[Actual_Volume],0) = 0 and
                coalesce (pls.[Actual_Sales_Dollars],0) = 0
                THEN 0
        ELSE (pls.[Actual_Sales_Dollars]/pls.[Actual_Volume])
    END
    AS 'AP'
    ,pls.production_date
  ,[dbo].[PriMonthAvgPrice](@endofmonth,@begofmonth, pls.plant_code) AS 'PriMoAvgPrice'

我的基本理解是我已经创建了一个标量函数。但是,根据我一直在阅读的有关我的错误的信息,此错误会在 TVF 上返回。这是真的?我在处理之前创建了一个 SVF,只是确定了前一个月的结束日期,因此它不像我在 UDF 中创建查询那样复杂。

我需要将其更改为 TVF 吗?如果是这样,当我必须加入多个表时如何合并 SELECT *?

提前致谢。

亚伦

【问题讨论】:

  • 那里也有FROM 子句吗?
  • 我有点怀疑,因为我在您的函数中看到了一个带有数据库名称 (woodproduction.dbo.plywood_layup_sales) 的表引用。您是否在创建函数的同一数据库中运行此查询?
  • pls.[Actual_Sales_Dollars]/pls.[Actual_Volume]) = 如果两列都是整数,请注意此处的整数数学。另外,我通常会在任何除法中进行除以零检查,这样如果底部数字为 0 或 null,它就不会停止。你知道你的数据,也许它不是必需的,但这是一个好习惯。很多次我都有一个意想不到的零。
  • SELECT * 不应在生产代码中使用,尤其是在存在连接时。它效率低下,并导致数据库通过 newtork 发送的信息比需要的多(连接字段重复)。
  • @HLGEM 我想了很多,整个查询中有很多连接。我为这个报告中的另一个数据集做了一个基本的 UDF,但它不涉及使用这样的查询。这只是一个 DATE UDF。

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


【解决方案1】:

你没有显示 from 子句,但是你创建的数据库是它的一部分吗?

如果您完全限定名称(包括数据库),它是否有效?

您是否独立测试过该功能:

select [dbo].[PriMonthAvgPrice] ('01/01/2011', '02/01/2011', 'test')

注意:当然你会使用一些应该返回结果的实际值。

请运行它并告诉我们返回的值:

 SELECT Actual_Sales_Dollars,Actual_Volume, pls.PLant_code          
 FROM   woodproduction.dbo.plywood_layup_sales pls         
 WHERE  Production_Date between '09-01-2011'  and  '09-30-2011'          
        and actual_volume <> 0      

【讨论】:

  • 对不起@JNK。我知道我会错过一些东西。 FROM woodproduction.dbo.plywood_layup_sales pls inner join @Production p n p.plant_number = pls.plant_number and p.production_date = pls.production_date WHERE MONTH (p.production_date)= Month (@monthtodate) and pls.actual_volume &lt;&gt; 0
  • @Joe Stefanelli:我是。同样的查询也在我对数据集的主要查询中。但在这种情况下,UDF 正在获取上个月末的数据并将其插入到设置为返回 MTD 的数据集中。所以有人告诉我这是最好的方法。我尽量模仿之前的 UDF。
  • 我做到了。它是否正确是另一回事。目前我得到NULL。我知道查询本身可以工作,所以我不确定为什么我会得到 NULL。我的老板说这很容易。当然,如果我有超过 3 个月的 SQL 经验。还有基本的 SQL。
  • 所以当你在上面的选择中单独运行 udf 代码时,你会得到 null>
  • @HGLEM 是的。但我也可能设置错误。因为这是他们在学校不教的东西,至少在我的,当我无法访问我们的其他 sql 人员之一时,我正在谷歌搜索所有内容。现在经常这样。我认为我正确设置了这个测试:` declare @date1 datetime declare @date2 datetime set @date1 = '09-01-2011' set @date2 = '09-30-2011' Select plant_code, actual_volume, dbo.PriMonthAvgPrice(@ date1,@date2, pls.plant_code) AS 'PriMoAvgPrice' from woodproduction.dbo.plywood_layup_sales pls where production_date between @date1 and @date2` AVGPRICE retns NULL
猜你喜欢
  • 2019-05-11
  • 1970-01-01
  • 2021-08-15
  • 2010-11-08
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多