Tsql SQL Server 2012:存储过程中的动态交叉表

Tsql SQL Server 2012:存储过程中的动态交叉表,tsql,sql-server-2012,local,Tsql,Sql Server 2012,Local,我试图使用存储过程在两个声明的变量@rvar(作为rowvariable)和@cvar(作为columnvariable)之间创建一个透视表。关键是在执行存储过程时,使用这两个变量作为动态输入,从VBA调用存储过程 我的代码有三个部分: 创建测试数据 申报本地人 在交叉表中查找列名称存储在新的local@sql1中 使用@sql1中存储的名称使用数据透视函数执行交叉表 我的问题:下面的代码可以工作,但我想让它成为定义列结构的变量的动态变量-当前设置为“q10_1_resp”-因此我只需声明局部@

我试图使用存储过程在两个声明的变量@rvar(作为rowvariable)和@cvar(作为columnvariable)之间创建一个透视表。关键是在执行存储过程时,使用这两个变量作为动态输入,从VBA调用存储过程

我的代码有三个部分:

  • 创建测试数据
  • 申报本地人
  • 在交叉表中查找列名称存储在新的local@sql1中
  • 使用@sql1中存储的名称使用数据透视函数执行交叉表
  • 我的问题:
    下面的代码可以工作,但我想让它成为定义列结构的变量的动态变量-当前设置为“q10_1_resp”-因此我只需声明局部@cvar,并在第3部分中使用它(如第4部分)。我已经成功地将第3部分转换为sql字符串并随后执行,但是@sql1中存储的列名不能在第4部分的代码中使用(我想这是一个范围问题)


    在大量尝试全球化scalarvariable但未成功之后,使用临时表存储字符串是关键。在存储过程开始时创建的临时表可以在整个过程中分配和引用。因此,在执行@sql时赋值,然后在执行@sql2时引用字符串。我希望这是有道理的

    CREATE PROCEDURE [dbo].[sp_crosstab] 
        -- Add the parameters for the stored procedure here
        @rvar nvarchar(max) = '',
        @cvar nvarchar(max) = '',
        @data nvarchar(max) = '',
        @sql nvarchar(max) = '',
        @sql2 nvarchar(max) = '',
        @sql3 nvarchar(max)=''
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
    create table #temp_crosstab
    (
       sqlstr nvarchar(max)
    )
    
    set @sql ='
    declare @sql1 nvarchar(max) = char(00)
    select @sql1 = @sql1 + [a].[col] + char(44)
        from
            (select distinct QUOTENAME(' + @cvar + ') as [col]
            from ' + @data + '
            group by ' + @cvar + ') as a
    
        SET @sql1 = left(@sql1, len(@sql1) - 1)
    
    
    insert into #temp_crosstab values (@sql1)'
    
    execute sp_executesql @sql
    
    
    select @sql3 = [sqlstr] from #temp_crosstab
    
    set @sql2 = '
    
    select ' + @rvar + char(44) +
            @sql3 + 'from (Select '
            + @rvar + char(44) + ' ' 
            + @cvar
            + ' from ' + @data + ') sq pivot(count(' 
            + @cvar 
            + ') for '
            + @cvar + ' IN ('+@sql3+')) as pt'
    
    
    exec sp_executesql @sql2
        END
    GO
    

    我们可以针对您的问题运行的样本数据和预期结果将帮助我们帮助您。在SO上有很多动态枢轴的例子;还有,这里的不是交叉表,而是一个
    PIVOT
    查询。虽然2实现了相同的结果,但交叉表的限制性要小得多。在我看来,这些示例没有帮助,因为您仍然必须在存储过程中硬编码列名(我希望通过将其设置为本地来避免这种情况)。什么示例?你还没有链接到任何;或者回应了我的任何评论。就像这个例子[-这里你仍然需要手动输入“c.category”。或者我的观点不清楚?
    CREATE PROCEDURE [dbo].[sp_crosstab] 
        -- Add the parameters for the stored procedure here
        @rvar nvarchar(max) = '',
        @cvar nvarchar(max) = '',
        @data nvarchar(max) = '',
        @sql nvarchar(max) = '',
        @sql2 nvarchar(max) = '',
        @sql3 nvarchar(max)=''
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
    create table #temp_crosstab
    (
       sqlstr nvarchar(max)
    )
    
    set @sql ='
    declare @sql1 nvarchar(max) = char(00)
    select @sql1 = @sql1 + [a].[col] + char(44)
        from
            (select distinct QUOTENAME(' + @cvar + ') as [col]
            from ' + @data + '
            group by ' + @cvar + ') as a
    
        SET @sql1 = left(@sql1, len(@sql1) - 1)
    
    
    insert into #temp_crosstab values (@sql1)'
    
    execute sp_executesql @sql
    
    
    select @sql3 = [sqlstr] from #temp_crosstab
    
    set @sql2 = '
    
    select ' + @rvar + char(44) +
            @sql3 + 'from (Select '
            + @rvar + char(44) + ' ' 
            + @cvar
            + ' from ' + @data + ') sq pivot(count(' 
            + @cvar 
            + ') for '
            + @cvar + ' IN ('+@sql3+')) as pt'
    
    
    exec sp_executesql @sql2
        END
    GO