2009-10-14 116 views
0

我有一个工作对数据库中几个表中的行执行多个验证检查。如果检查失败,它将在表中记录失败。记录的信息包括表名,失败行的唯一标识符值,检查失败的行,以及当时正在运行哪个作业。这里的日志TSQL函数从函数返回结果集中的行数

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) 

我想编写一个返回给某个表和作业ID失败的行数的函数(即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 [email protected] And [email protected] 
        Group By fkJobID, TableName, TableUniqueIdentifier 

    SET @NumFailedRows = @@ROWCOUNT 

    RETURN @NumFailedRows  
END 

但是,当然,您不能在函数内部具有该Select语句。有没有办法做到我想在一个函数内部做的事情,还是我必须这样做存储过程路线?

回答

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 [email protected] 
    And [email protected] 
    Group By fkJobID, TableName, TableUniqueIdentifier 
    ) a 

RETURN @NumFailedRows 

END 
+0

感谢这工作。我之前尝试过,没有别名,它有一个语法错误。你知道为什么最后需要a吗? – 2009-10-15 15:32:18

+0

很高兴我能帮到你。我不能确切地说明为什么需要别名,除非说所有的字段必须能够被完全限定(大多数情况下,引擎会为你处理),并且没有派生名称表/结果集,您没有任何引用字段的来源的名称。只是猜测,但。 – 2009-10-15 21:05:38

4

你可以在你选择使用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 [email protected] And [email protected] 
       Group By fkJobID, TableName, TableUniqueIdentifier 

--SET @NumFailedRows = @@ROWCOUNT 

RETURN @NumFailedRows  
END 
+0

不幸的是,这将只是给我多少不同的测试特定的行失败的次数;例如如果UniqueIdentifier = 1且fkJobID = 1且TableName ='table1'且该行失败fkValidationFieldFailureType 1,6和7 Count(*)将返回3.基本上这样做会返回测试失败的每行的计数 – 2009-10-14 22:26:28

+0

您需要将其包裹,以便COUNT(*)是组的计数,而不是每组中的计数。 – 2009-10-15 04:49:57

1

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

SELECT COUNT(*)OVER()作为TOTAL_ROWS,... 从...