TSQL函数从函数返回结果集中的行数

时间:2009-10-14 21:26:27

标签: sql sql-server tsql user-defined-functions

我有一项工作,可以对数据库中多个表中的行执行多次验证检查。如果检查失败,则将失败记录在表中。记录的信息包括表名,失败行的uniqueidentifier值,检查失败以及当时正在运行的作业。这是日志的简化表定义

CREATE TABLE [tblSY_ValidationFieldFailures](
    [pkValidationFieldFailure] [int] IDENTITY(1,1) NOT NULL,
    [fkJobID] [int] NOT NULL,
    [fkValidationFieldFailureType] [int] NOT NULL,
    [TableName] nvarchar(128),
    [TableUniqueIdentifier] [nvarchar](100) NULL)

我想写一个函数,它返回给定某个表和jobID失败的行数(即fnGetNumberOfFailedRows(@JobID,@ TableName))。我尝试了类似以下内容:

CREATE FUNCTION fnGetNumberOfRowsThatFailedValidationCheck 
(
    @pkJobID int,
    @TableName nvarchar(128)
)
RETURNS int
AS
BEGIN
    -- Declare the return variable here
    DECLARE @NumFailedRows int

    Select fkJobID, 
           TableUniqueIdentifier, 
           TableName 
    From tblSY_ValidationFieldFailures
        Where fkJobID=@pkJobID And TableName=@TableName
                    Group By fkJobID, TableName, TableUniqueIdentifier

    SET @NumFailedRows = @@ROWCOUNT

    RETURN @NumFailedRows    
END

但是当然你不能在函数中包含Select语句。有没有办法在函数内部执行我想要的操作,还是必须执行存储过程路由?

3 个答案:

答案 0 :(得分:4)

您可以在select中使用count(*)语句,并正确分配,例如:

CREATE FUNCTION fnGetNumberOfRowsThatFailedValidationCheck 
(
    @pkJobID int,
    @TableName nvarchar(128)
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @NumFailedRows int

Select @NumFailedRows = count(*) 
From tblSY_ValidationFieldFailures
    Where fkJobID=@pkJobID And TableName=@TableName
                Group By fkJobID, TableName, TableUniqueIdentifier

--SET @NumFailedRows = @@ROWCOUNT

RETURN @NumFailedRows    
END

答案 1 :(得分:3)

这应该适合你:

    CREATE FUNCTION fnGetNumberOfRowsThatFailedValidationCheck 
    (   
    @pkJobID int,    
    @TableName nvarchar(128)
    )
RETURNS int
AS

BEGIN

-- Declare the return variable here
DECLARE @NumFailedRows int

SELECT @NumFailedRows = count(*) 
FROM (
    Select 
        fkJobID,            
        TableUniqueIdentifier,            
        TableName 
    From tblSY_ValidationFieldFailures    
    Where fkJobID=@pkJobID
    And TableName=@TableName
    Group By fkJobID, TableName, TableUniqueIdentifier
    ) a

RETURN @NumFailedRows

END

答案 2 :(得分:1)

在SQL Server 2008及更高版本中,添加COUNT(*)OVER()作为查询中的列名称之一,并将使用返回的总行填充。它在每一行中重复,但至少可以获得该值。许多其他解决方案不起作用的原因在于,对于非常大的结果集,在迭代所有行之后,您将不知道总数,这在许多情况下是不实际的(尤其是顺序处理解决方案)。例如,在调用第一个IDataReader.Read()之后,此技术为您提供总计数。

选择COUNT(*)OVER()作为Total_Rows,... 来自......