0

我创建了用于将垂直表数据转换为水平表的查询,并且我的declare查询中有一条语句。

我必须根据我的查询创建一个视图,但我从 SQL Server 收到一个错误,因为我的declare查询中有一条语句。

我试图变成视图的查询:

declare @columnName nvarchar(max)
declare @query nvarchar(max)

select 
    @columnName = COALESCE(@columnName + ', ', '') + QUOTENAME(element_name) 
from 
    (select distinct 
         element_name 
     from 
         elements e 
     join 
         form_elements fe on fe.element_id = e.id 
     join 
         form on fe.form_id = form.id and form.id = 1) as B

set @query = 'select *
              from 
                  (select fi.index_key as incidnet_id, e.element_name as col_name, fev.value as value
                   from form_element_values fev
                   join form_index fi on fev.form_index_id = fi.id
                   join form_elements fe on fev.form_element_id = fe.id
                   join elements e on fe.element_id = e.id
                   join form f on fi.form_id = f.id
                   where f.id = 1) as SourceData 
              PIVOT(max(value) for col_name in (' + @columnName + ')) as pivotTable'

exec(@query)

此查询从垂直表中获取数据并将其显示在水平列中

由于我的列名是动态的,我必须创建一个局部变量,但现在我很难将此查询转换为视图。

这个查询还有其他选择,所以我不必使用局部变量吗?

4

1 回答 1

0

这不能变成一个视图。如果您检查文档,CREATE VIEW您会发现它表明视图的主体只是一个简单的SELECT语句,没有别的。它不接受任何类型的控制流、变量或任何其他主体,只是一个带有一些限制的单独选择。

数据库中的视图就是一个SELECT存储在数据库中的视图,可以从中进行和扩展查询,但仅此而已。在这种情况下,您的查询需要动态 SQL,而这超出了视图的能力。正如您在评论中指出的那样,函数也不可能,因为它们不能有任何可能产生副作用的东西,并且运行一批动态 SQL 几乎可以做任何事情,因此它们在那里被禁止。

将其保留在数据库端的唯一选择是使用存储过程。评论中还指出,除了使用结果集之外,您无法对结果集执行任何操作(至少不是以任何简单的方式,请在此处查看一些详细信息,以及在此问题上)。

另一个可行的替代方案是在客户端完成所有这些工作,让数据库只运行查询。您将发出第一个选择以获取所需的列,然后使用您的客户端语言发出另一个执行PIVOT.

于 2018-03-15T23:57:54.220 回答