51

SQLServer用のMicrosoftOLEDBプロバイダーの一部のバージョン(主にWindows XP)がWITHステートメントをサポートしていないことを理解しました。そこで、SQLステートメントをテーブル値関数に移動し、アプリケーションから呼び出すことにしました。今、私は立ち往生しています。INSERT INTOステートメントをどのように使用する必要がありWITHますか?これが私がこれまでに持ってきたコードですが、SQLServerはそれを好きではありません...:-(

CREATE FUNCTION GetDistributionTable 
(
    @IntID int,
    @TestID int,
    @DateFrom datetime,
    @DateTo datetime
)
RETURNS 
@Table_Var TABLE 
(
    [Count] int, 
    Result float
)
AS
BEGIN
INSERT INTO @Table_Var ([Count], Result) WITH T(Result)
     AS (SELECT ROUND(Result - AVG(Result) OVER(), 1)
         FROM RawResults WHERE IntID = @IntID AND DBTestID = @TestID AND Time >= @DateFrom AND Time <= @DateTo)
SELECT COUNT(*) AS [Count],
       Result
FROM   T
GROUP  BY Result

    RETURN 
END
GO
4

3 に答える 3

66

テーブル値関数のCTEの構文は次のようになります。

CREATE FUNCTION GetDistributionTable 
(
    @IntID int,
    @TestID int,
    @DateFrom datetime,
    @DateTo datetime
)
RETURNS TABLE
AS
RETURN  
(
    WITH cte AS
    (
        SELECT ROUND(Result - AVG(Result) OVER(), 1) Result
        FROM   RawResults 
        WHERE  IntID = @IntID 
        AND    DBTestID = @TestID 
        AND    Time >= @DateFrom 
        AND Time <= @DateTo    
    )

    SELECT  COUNT(*) AS [Count],
            Result
    FROM    cte
    GROUP  BY 
            Result
)
GO

可能であれば、CTE(WITHステートメント)を省略して、代わりにサブクエリを使用するインラインテーブル値関数を作成することもできます。

CREATE FUNCTION GetDistributionTable 
(
    @IntID int,
    @TestID int,
    @DateFrom datetime,
    @DateTo datetime
)
RETURNS TABLE
AS
RETURN  
(
    SELECT  COUNT(*) AS [Count],
            Result
    FROM    (
                 SELECT ROUND(Result - AVG(Result) OVER(), 1) Result
                 FROM   RawResults 
                 WHERE  IntID = @IntID 
                 AND    DBTestID = @TestID 
                 AND    Time >= @DateFrom 
                 AND Time <= @DateTo    
    ) t
    GROUP  BY 
            Result
)
GO

あなたの例はマルチステートメントTVF(挿入して選択)を使用しているようですが、マルチステートメントTVFはクエリオプティマイザーがより良い実行プランを選択するのを妨げる可能性があるため、インラインTVFを使用してみてください(パフォーマンスの違いはここで説明されています)

于 2013-02-26T10:25:58.017 に答える
18

このような..

CREATE FUNCTION GetDistributionTable 
(
    @IntID int,
    @TestID int,
    @DateFrom datetime,
    @DateTo datetime
)
RETURNS 
@Table_Var TABLE 
(
    [Count] int, 
    Result float
)
AS
BEGIN
  WITH T 
    AS (    
        select Ticket_Id,COUNT(1) Result from 
        Customer_Survey
        group by MemberID,SiteId,Ticket_Id
   )
  INSERT INTO @Table_Var ([Count], Result)
  SELECT COUNT(*) AS [Count],
       Result
  FROM   T
  GROUP  BY Result
  RETURN 
END
GO
于 2013-02-26T11:24:51.340 に答える
0
CTE with if else in UDF 

USE [SchoolDB]
GO

/****** Object:  UserDefinedFunction [dbo].[GetDistributionTable]    Script Date: 24-08-2019 05:17:55 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO





alter  FUNCTION [dbo].[GetDistributionTable] 
(
   @DepartmentName varchar(50) = 'Production'
)
RETURNS 
@Table_Var TABLE 
(   NUM int IDENTITY(1,1),
    [ParentEmployeeKey] int, 
    Result float
)
AS
BEGIN
Declare @Table_Vars table
(
    [ParentEmployeeKey] int, 
    Result float
);
insert into @Table_Vars([ParentEmployeeKey])
select COUNT(1) Result from 
        [SchoolDB].[dbo].[DimEmployee] where DepartmentName = @DepartmentName
if(@@rowcount >0)
begin
WITH T 
    AS (    
        select [ParentEmployeeKey],COUNT(1) Result from 
        [SchoolDB].[dbo].[DimEmployee] where DepartmentName = @DepartmentName
        group by [ParentEmployeeKey]
   )
  INSERT INTO @Table_Var ([ParentEmployeeKey], Result)
  SELECT COUNT(*) AS [Count],
       Result
  FROM   T
  GROUP  BY Result
end
else

 WITH T 
    AS (    
        select [ParentEmployeeKey],COUNT(1) Result from 
        [SchoolDB].[dbo].[DimEmployee] where DepartmentName = @DepartmentName
        group by [ParentEmployeeKey]
   )
  INSERT INTO @Table_Var ([ParentEmployeeKey], Result)
  SELECT COUNT(*) AS [Count],
       Result
  FROM   T
  GROUP  BY Result
  RETURN 
END



GO
于 2019-08-24T12:15:36.213 に答える