2016-12-21 40 views
2

我在SQL Server中有一个表,其中列出了报表中的各个部分。有三个字段:SectionID(数字自动编号主键),SectionTitle(报表部分的标题)和SourceView(本地数据库中返回报表记录的视图的名称)。从T-SQL函数返回视图中的记录数

我需要的是一个视图,它具有这三列加上显示由'SourceView'返回的记录数的第四列。 喜欢的东西:

CREATE myView AS 

SELECT 
    SectionID, 
    SectionTitle, 
    SourceView, 
    myFunction(SourceView) AS RowsInView 
FROM 
    tblBaseData 

我想这将是简单的写一个函数采取视图名称,返回的行数来实现。我最初的计划是在函数的主体中构建一些动态SQL。

CREATE FUNCTION myFunction(@ViewName VARCHAR) RETURNS INT AS 

BEGIN 

    DECLARE @RowCount INT 
    DECLARE @SQL VARCHAR(200) 
    SET @SQL = 'SET @RowCount = (SELECT COUNT(*) FROM ' + @ViewName + ')' 
    EXEC sp_executesql @SQL 
    RETURN ISNULL(@RowCount, 0) 

END 

但是,你不能在函数中使用EXEC,所以你不能运行动态SQL,你不能使用EXEC来运行它返回一个值的过程,并不能查询系统对象,因为 - 虽然这将适用于表格 - 它不适用于视图。

我曾尝试没有成功如下:

How to get the row count for views from a database?

Execute function inside view SQL server

https://msdn.microsoft.com/en-GB/library/ms188655.aspx

Create a function for counting rows from any table

我试图得到一个视图中工作,因为我需要显示带有当前记录的网页上的结果ord计数,否则我会建立一个表并定期刷新数据,

我假设我只是对这个问题采用了错误的方法。任何人都可以将我指向正确的方向吗?谢谢。

+0

基本回答了这个 - 由以下strickt01提供,则是可以更换包含返回表变量的过程的视图。这适用于报告服务和网络方法 - 因此,问题得以解决。感谢所有的帮助和时间。 – BBJones

回答

1

这是相当笨拙,但使用的过程,而不是一个视图会避开你已经在你的问题解决的问题:

CREATE PROCEDURE GetViewRowCounts 
AS 
BEGIN 
    DECLARE @sectionId int, @title varchar(50), @view varchar(50) 
    DECLARE @tbl_view_counts TABLE (section_id int not null, 
            title varchar(50) not null, 
            view_name varchar(50) not null, 
            view_count int not null) 
    DECLARE @RowCount INT 
    DECLARE @SQL NVARCHAR(200), @ParmDefinition NVARCHAR(100) 

    DECLARE c_vws CURSOR FAST_FORWARD FOR 
    SELECT 
    SectionID, 
    SectionTitle, 
    SourceView 
    FROM 
    tblBaseData 

    OPEN c_vws 

    FETCH NEXT FROM c_vws INTO @sectionId, @title, @view 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @ParmDefinition = N'@RowCountOUT int OUTPUT'; 
     SET @SQL = N'SELECT @RowCountOUT = COUNT(*) FROM ' + @view 

     EXEC sp_executesql @SQL, @ParmDefinition, @[email protected] OUTPUT; 

     INSERT @tbl_view_counts 
     VALUES (@sectionId, @title, @view, @RowCount) 

     FETCH NEXT FROM c_vws INTO @sectionId, @title, @view 
    END 

    CLOSE c_vws 
    DEALLOCATE c_vws 

    SELECT * FROM @tbl_view_counts 
END 
+0

这给了我一个表变量,但我看不到一种方法,然后使变量的内容可用于视图....我需要一个报告服务报告和一个Web方法,它提供了一个网页。除非我缺少明显的东西(这完全有可能),我仍然无法得到表变量的内容? – BBJones

+0

存储过程返回一个表。您可以选择存储过程(而不是视图)作为报告服务报告的数据源。同样,你可以在web方法中执行存储过程,而不是从视图中选择 - 它们都返回相同的东西(即表)。 – strickt01

+0

这看起来像正确的解决方案,但是当我尝试过程并执行它时(期待列表中的记录)时,我得到:消息214,级别16,状态2,过程sp_executesql,行1 过程期望参数'@statement '类型为'ntext/nchar/nvarchar'。 – BBJones

1

这会给你的计数回,而无需使用功能或知道视图的名称:

CREATE myView AS 

SELECT 
    SectionID, 
    SectionTitle, 
    SourceView, 
    COUNT(*) OVER() AS RowsInView 
FROM 
    tblBaseData 

编辑:道歉,我误解你的初始后。我认为,一个存储过程可能是最好的方式,但如果你想继续下去,方法,你可以有一个“查找”的说法,是这样的:

CREATE VIEW dbo.ViewCounts 
AS 

SELECT 'SourceView1' AS SourceViewName, 
     COUNT(*) OVER() AS RowsInView 
FROM SourceView1 
UNION 
SELECT 'SourceView2' AS SourceViewName, 
     COUNT(*) OVER() AS RowsInView 
FROM SourceView2 

-- etc... 

然后回来加入到它你原来的观点得到计数这样:

CREATE myView AS 

SELECT 
    t.SectionID, 
    t.SectionTitle, 
    t.SourceView, 
    vc.RowsInView 
FROM 
    tblBaseData t 
JOIN dbo.ViewCounts vc ON vc.SourceViewName = t.SourceView 

这是一个非常肮脏的方法(和观看次数,观看,如果你添加新的意见,将需要手动更新),但是如果你绝对需要坚持能够解决您的问题一个看法。

+0

这给了我一个错误,在管理工作室与“ORDER BY”子句,要清楚,虽然我不想计算'myView'中的行,我试图返回视图中命名' SourceView'字段 - 如果从我原来的问题中不清楚,请致歉。 – BBJones

+0

道歉,我的错。我想我已经修复了原始错误(它适用于SQL Server 2014),并且我添加了一个新的方法来考虑。它有点肮脏,但:) –

+0

感谢你,我同意它会提供记录计数,但我不能实现一个解决方案,需要每次添加到tblBaseData视图时需要编辑 - 任何解决方案必须工作不管对tblBaseData中记录的更改。 – BBJones