【问题标题】:How to use strings inside of a string for a dynamic PIVOT query in SQL Server如何在 SQL Server 中使用字符串中的字符串进行动态 PIVOT 查询
【发布时间】:2020-03-17 07:04:16
【问题描述】:

我想在 SQL Server 中编写一个动态数据透视查询来跨列分布某些类别。

查询包含一些WHERE 字符串过滤器。这就是为什么我需要在字符串中写入字符串。

这应该与 '' 一起使用以转义单引号,但它只会执行一次。

我知道我可以,但我想避免将每个字符串保存在另一个变量中,例如

@source
@id

因为这会导致在以后的查询中声明很多变量,我想在这些查询中使用更多 WHERE 子句进行过滤。

这是我尝试过的,结果如何:

  DECLARE @cols  AS NVARCHAR(MAX),
          @query AS NVARCHAR(MAX),
          @id    AS NVARCHAR(MAX);

--get wanted category names   
  WITH somecategories AS(
      SELECT DISTINCT
      categories AS cats
      FROM sometable
      WHERE foo = 9)
-- remove last comma
    SELECT
          @columns+=QUOTENAME(descr) + ','
    FROM
          distdescription;

SET @columns = LEFT(@columns, LEN(@columns) - 1);
SET @id = '12345'

set @query = 'SELECT * from 
            (
                select date
                    , amount
                    , id
                    , source
                    , category
                from temp
                where source = ''location''
                  and id = '''+ @id + '''
           ) x
            pivot 
            (
                 max(amount)
                for category in (' + @cols + ')
            ) p '

执行(@query)

结果 有效。

  DECLARE @cols  AS NVARCHAR(MAX),
          @query AS NVARCHAR(MAX);

--get wanted category names   
  WITH somecategories AS(
      SELECT DISTINCT
      categories AS cats
      FROM sometable
      WHERE foo = 9)
-- remove last comma
    SELECT
          @columns+=QUOTENAME(descr) + ','
    FROM
          distdescription;


SET @columns = LEFT(@columns, LEN(@columns) - 1);

set @query = 'SELECT * from 
            (
                select date
                    , amount
                    , id
                    , source
                    , category
                from temp
                where source = ''location''
                  and id = ''12345''
           ) x
            pivot 
            (
                 max(amount)
                for category in (' + @cols + ')
            ) p '

**结果:**

')' 附近的语法不正确。

然后我实际上发现我首先不需要 id 过滤器所以我将其更改为:

      DECLARE @cols  AS NVARCHAR(MAX),
              @query AS NVARCHAR(MAX),

    --get wanted category names   
      WITH somecategories AS(
          SELECT DISTINCT
          categories AS cats
          FROM sometable
          WHERE foo = 9)
    -- remove last comma
        SELECT
              @columns+=QUOTENAME(descr) + ','
        FROM
              distdescription;

    SET @columns = LEFT(@columns, LEN(@columns) - 1);

    set @query = 'SELECT * from 
                (
                    select date
                        , amount
                        , id
                        , source
                        , category
                    from temp
                    where source = ''location''
               ) x
                pivot 
                (
                     max(amount)
                    for category in (' + @cols + ')
                ) p '
execute(@query)

*结果:

')' 附近的语法不正确。

然后我尝试在不使用 PIVOT 命令的情况下运行查询:

SELECT * from 
                    (
                        select date
                            , amount
                            , id
                            , source
                            , category
                        from temp
                        where source = 'location'
                   ) x

SELECT * from 
                    (
                        select date
                            , amount
                            , id
                            , source
                            , category
                        from temp
                        where source = 'location'
                          and id = '12345'
                   ) x

两者都可以正常工作。

如果我使用

select @query

输出以:

结尾
SELECT some data,
       some other data,
       the content of @columns
) p

它应该是什么样子的:

SELECT some data,
           some other data,
           the content of @columns
  FROM some table
    )x
 pivot 
            (
                 max(amount)
                for category in (' + @columns + ')
            ) p 

因此,PIVOT 函数的一部分被删除了。 我应该补充一点,真正的查询要长得多(一个 4376 个字符的字符串)。

【问题讨论】:

  • 你是print@Query吗??
  • execute(@query)之前写一个代码Print @query!!!
  • 您应该使用sp_executesql 参数化您的动态语句而不是'...id = '''+ @id + '''...'。我假设类似于'... id = @id ...' 然后EXEC sp_executesql @query, N'@id int', @id; 将未经处理的值注入动态语句是一个糟糕的想法。
  • 在查询结束前打印停止。如果我使用:and id = ''12345'' 它是打印停止的另一行,然后当我简单地删除该行但两次它都在查询的后面部分中离该行不远...
  • 然后使用 SELECT, @Sebban 。 PRINT 最多只能返回 4,000 个字符。

标签: sql-server string dynamic pivot


【解决方案1】:

我解决了这个问题。

https://dba.stackexchange.com/questions/36081/write-differences-between-varchar-and-nvarchar

"您需要确保在 Unicode 字符串文字前加上 N 前缀。”

所以SET @query =N'...' 解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多