【发布时间】: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