1

Inline table function我在 SQL Server 2008 R2 中创建了一个,我意识到一些查询返回任何记录。所以我想当这种情况发生时,返回一个包含所有空列的记录。

举例:

Col1   Col2   Col3
NULL   NULL   NULL

更新:这是功能

ALTER FUNCTION [dbo].[GetWorksheetSummaryByObjective](@objectiveId [smallint], @testTemplateId [smallint])
RETURNS @resultTable TABLE (
    [AnsweredWorksheetId] [smallint] NOT NULL,
    [LastDate] [date] NULL,
    [BestScore] [smallint] NULL,
    [ShouldBeMakeUp] [tinyint] NOT NULL
)
AS 
BEGIN

    INSERT @resultTable
    SELECT TOP 1 B.Id AS AnsweredWorksheetId, A.Date, CONVERT(smallint, B.Score * 100),
        CASE
        WHEN B.Score >= 0.7 THEN 0
        ELSE 1
        END AS ShouldBeMakeUp
    FROM AnsweredTest AS A
    RIGHT JOIN AnsweredWorksheet AS B ON (A.Id = B.AnsweredTestId)
    WHERE B.ObjectiveId = @objectiveId AND A.ExamTemplateId = @testTemplateId
    ORDER BY B.Score DESC

    RETURN
END
4

3 回答 3

1

您发布的功能不是内联 TVF。

鉴于基础查询最多返回 1 行,因为TOP 1没有SELECT MAX()aGROUP BYHAVING总是返回单行,您可以将其作为内联 TVF 执行,但如下所示。

CREATE FUNCTION [dbo].[Getworksheetsummarybyobjective](@objectiveId    [SMALLINT],
                                                       @testTemplateId [SMALLINT])
RETURNS TABLE
AS
    RETURN
      (SELECT Max(AnsweredWorksheetId) AS AnsweredWorksheetId,
              Max([LastDate])          AS [LastDate],
              Max([BestScore])         AS [BestScore],
              Max(ShouldBeMakeUp)      AS ShouldBeMakeUp
       FROM   (SELECT TOP 1 B.Id                             AS AnsweredWorksheetId,
                            A.Date                           AS [LastDate],
                            CONVERT(SMALLINT, B.Score * 100) AS [BestScore],
                            CASE
                              WHEN B.Score >= 0.7 THEN 0
                              ELSE 1
                            END                              AS ShouldBeMakeUp
               FROM   AnsweredTest AS A
                      RIGHT JOIN AnsweredWorksheet AS B
                        ON ( A.Id = B.AnsweredTestId )
               WHERE  B.ObjectiveId = @objectiveId
                      AND A.ExamTemplateId = @testTemplateId
               ORDER  BY B.Score DESC) T) 
于 2012-10-27T19:59:04.093 回答
0

像这样的东西会起作用吗?

declare @tbl table
(
  Col1 int, Col2 int, Col3 int
)

insert @tbl (Col1, Col2, Col3)
     select Col1, Col2, Col3 from SomeTable where blah = blah

if exists (select 1 from @tbl)
begin
    select Col1, Col2, Col3 from @tbl
end
else
begin
    select null Col1, null Col2, null Col3
end
于 2012-10-27T19:21:44.320 回答
0

好的,跳过我的其他答案 - 没有意识到表函数有多么严格。我有另一个想法 - 这个应该可以工作,但这意味着必须在函数中运行 WHERE 两次,因此将资源加倍来进行调用:

CREATE FUNCTION dbo.SomeTest
    ( @i int ) 
RETURNS TABLE
as
RETURN 
    select Col1, Col2 from SomeTable
    where Whatever = Whatever

    union all

    select null Col1, null Col2
    where not exists (select 1 from SomeTable where Whatever = Whatever)
go

编辑:想到另一种方法来做到这一点,而无需双重浸渍:

create function dbo.SomeTest
    ( @i int )
returns table
as
return
select t.Col1, t.Col2 from 
(
    select Col1, Col2
    from SomeTable
    where Whatever = Whatever
) t
right join
(
    select 1 testcol
) x on c.Col1 is not null
go

这假定 Col1 是一个非空列。

于 2012-10-27T19:50:55.727 回答