将列添加到SSRS / SQLServer 2005中的PIVOTing存储过程

时间:2014-04-09 16:57:34

标签: sql-server-2005 stored-procedures reporting-services

我需要将REGION列添加到SSRS报告中,该报告依赖于人口的存储过程。在存储过程中,它使用数据透视表。我知道这种关系存在于一个单独的表中,所以我认为这是将JOIN放在正确的位置的问题,但我是否在正确的轨道上?我注意到我认为它应该放在下面代码中的注释中:

USE [TEST]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[abc_sp_ACE_GetFormDataNoContactID]
@FormObjectKey varchar(100)
as
DECLARE @SEQN varchar(5)

--CREATE TEMP TABLE
CREATE table #tmpFormData
(ID varchar(10) NOT NULL
)

DECLARE @ItemName varchar(50), @TableName varchar(50), @SQL varchar(max), @vary varchar(1000), @final varchar(max)
DECLARE @ItemList varchar(max),@ItemListUnPivot varchar(max),@DataType varchar(20),@Prompt varchar(500)
SET @ItemList = ''
SET @ItemListunPivot = ''

DECLARE contact_cursor CURSOR FOR
select ItemName,TableName,Prompt
from abc_ACE_Form Form
    join abc_ACE_FormItem FormItem 
        on Form.objectkey = FormItem.formkey
where Form.objectKey = @FormObjectKey
and FormItem.isVisible = 1 and itemtype not in ('ContentBlock','Divider')
order by PositionNumber

OPEN contact_cursor

FETCH NEXT FROM contact_cursor
INTO @ItemName, @TableName, @Prompt

-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN
    --Get DATA TYPE
    SELECT @DataType = 
        CASE t.name 
            WHEN 'varchar' THEN 'varchar(' + Convert(varchar(10),c.max_length) + ')'
            WHEN 'float' THEN 'varchar(200)'
            ELSE t.name
        END
        FROM sys.objects a
            JOIN sys.columns AS c
                on c.object_id = a.object_ID
        JOIN sys.types AS t ON c.user_type_id=t.user_type_id
        WHERE c.name = @ItemName
        and a.Name = @TableName


    SELECT @SQL = 'ALTER TABLE #tmpFormData' 
    select @vary = ' ADD ' + @ItemName + ' ' + @DataType
    select @final = @sql + @vary
    Exec ( @final)

    If len(@ItemList) = 0
        BEGIN
            Select @ItemList = @ItemList + @ItemName
        END
    ELSE
        BEGIN
            Select @ItemList = @ItemList + ',' + @ItemName 
        END

    if len(@ItemListUnPivot) = 0
        BEGIN
            Select @ItemListUnPivot = 'convert(varchar(100),' + @ItemName + ') as ' + @ItemName 
        END
    ELSE
        BEGIN
            Select @ItemListUnPivot = @ItemListUnPivot + ',' + 'convert(varchar(100),' + @ItemName + ') as ' + @ItemName
        END


   -- This is executed as long as the previous fetch succeeds.
   FETCH NEXT FROM contact_cursor
   INTO @ItemName, @TableName, @Prompt
END

CLOSE contact_cursor
DEALLOCATE contact_cursor

SET @SQL = ''

SELECT @SQL = 'INSERT INTO #tmpFormData (ID,' + @ItemList + ')'
Select @SQL = @SQL + ' select ID, ' + @ItemList + ' from ' + @Tablename 
SELECT @SQL = @SQL + ' join abc_ACE_formtrans on convert(varchar(128),trankey) = workflowtran_key where formkey = ''' + @FormObjectKey + ''''
EXEC(@SQL)

SELECT @SQL = 'SELECT ID, measure, value, '''' as ChapterName, '''' as FormTitle, region  
    FROM( select ID, ' + @ItemListUnPivot + ' from #tmpFormData) p UNPIVOT( VALUE FOR measure IN (' + @ItemList + ')) AS unpvt'
    -- ADDED 'region' HERE...I think this is where the JOIN to the table 'REG' should go

CREATE TABLE #tmp (ID int, measure varchar(500), value varchar(500), ChapterName varchar(80), FormTitle varchar(255), region varchar(4))
INSERT INTO  #tmp (ID, measure, value, ChapterName, FormTitle, region)
        --ADDED REGION TO BOTH CREATE AND INSERT STATEMENTS


EXEC (@SQL)

update #tmp
set measure = Prompt
    , ChapterName = nm.Company
    , FormTitle = Form.Title
from abc_ACE_Form Form
    join abc_ACE_FormItem FormItem 
        on Form.objectkey = FormItem.formkey
    join #tmp a
        on FormItem.ItemName = measure
    left join Name nm 
        on nm.ID = a.ID
where Form.objectKey = @FormObjectKey
and FormItem.isVisible = 1

SELECT * from #tmp order by ChapterName, ID

drop table #tmp
drop table #tmpFormData

甚至可以做到吗?我需要重写SP(请说不)?

更新:有人提到我可以将SP的结果写入临时表,然后将临时表连接到具有附加列的表。一个很好的答案,但我似乎无法找到添加连接的过程。我的第一个猜测,经过2个小时的试验和错误是在创建#tmp文件之前添加它,是吗?

UPDATE2:好的,我在最后一个SELECT语句(SELECT * FROM #tmp)中添加了JOIN,将*更改为#tmp中的所有列并添加了region列。我趟过SSRS,可以看到列填充(yay!),但后来我翻过来预览报告,它吹走了大约30列(嘘!)。这就像改变吹动了数据透视表一样,但是在程序中已经发生了枢轴/非透视,为什么会这样做呢?

2 个答案:

答案 0 :(得分:1)

我不会尝试动态地在SQL中转移数据 - 因为您发现这非常复杂,任何更改都可能会破坏下游流程。

SSRS可以使用列组执行此任务。

答案 1 :(得分:0)

虽然@ Mike-Honey的回答有助于我指出如何在SSRS报告中添加该列,但我最终决定更改SP,因为决定区域数据对于未来的报告是必要的。我编写了最后一个SELECT语句,如下所示:

SELECT 
A.ID -- EXPANDED FROM * IN ORDER TO INCLUDE ADDITIONAL COLUMN 
, A.measure
, A.value
, A.ChapterName
, A.FormTitle
, DC.CH_COL_REGION -- ADDED 
from #tmp A
    JOIN DEMO_CHAPTER DC -- ADDED 
    ON A.ID = DC.ID -- ADDED 
order by A.ChapterName, A.ID