我有一个动态SQL查询,可以在执行后获取结果集。但是,我从SQL服务器引擎返回结果的UI模型并没有提供渲染查询列名的方法。
由于查询的动态特性,我无法在设计时对列名进行硬编码。所以我的问题是如何获取列名以及查询返回的数据集?
此查询:
DECLARE @SQLSTATMENT nvarchar(1000)
SELECT @SQLSTATEMENT = '
SELECT
convert(date, DATEADDED) DATEADDED
,COUNT(1) as NUMBEROFRECORDS
FROM
dbo.CONSTITUENT
GROUP BY
convert(date, DATEADDED)
ORDER BY
convert(date, DATEADDED) DESC
'
Exec (@SQLSTATEMENT);
给我这张桌子(Original Image):
+ ---------- + --------------- +
| DATEADDED | NUMBEROFRECORDS |
+ ---------- + --------------- +
| 2017-03-14 | 1 |
| 2017-03-10 | 1 |
| 2016-07-07 | 5 |
| 2016-06-29 | 3 |
| 2016-06-15 | 1 |
| 2014-11-11 | 465 |
| 2005-06-09 | 11 |
| 2005-04-13 | 1 |
| 2005-02-28 | 2 |
+ ---------- + --------------- +
但我想要这个(Original Image):
+ ---------- + --------------- +
| DATEADDED | NUMBEROFRECORDS |
+ ---------- + --------------- +
| DATEADDED | NUMBEROFRECORDS |
| 2017-03-14 | 1 |
| 2017-03-10 | 1 |
| 2016-07-07 | 5 |
| 2016-06-29 | 3 |
| 2016-06-15 | 1 |
| 2014-11-11 | 465 |
| 2005-06-09 | 11 |
| 2005-04-13 | 1 |
| 2005-02-28 | 2 |
+ ---------- + --------------- +
由于
答案 0 :(得分:1)
这是可行的,但不是很漂亮。传递动态SQL的存储过程将更加清晰
我们实际上是在动态SQL中执行动态SQL
一个警告:我保留了RN
字段示例(使用我的FRED系列数据)
-- This is Your Base/Initial Query, or the only portion you need to supply
Declare @SQL varchar(max) = 'Select Updated as Updated,Count(*) as NumberOfRecords From [dbo].[FRED-Series] Group By Updated'
Select @SQL = '
;with cte0 as ('+@SQL+')
, cte1 as (Select *,RN = Row_Number() over (Order By (Select null)) From cte0 )
, cte2 as (
Select A.RN,C.*
From cte1 A
Cross Apply (Select XMLData=cast((Select A.* for XML Raw) as xml)) B
Cross Apply (
Select Item = attr.value(''local-name(.)'',''varchar(100)'')
,Value = attr.value(''.'',''varchar(max)'')
,ColNr = Row_Number() over (Order By (Select Null))
From B.XMLData.nodes(''/row'') as A(r)
Cross Apply A.r.nodes(''./@*'') AS B(attr)
Where attr.value(''local-name(.)'',''varchar(100)'') not in (''RN'')
) C
)
Select Distinct RN=0,Item,Value=Item,ColNr Into #Temp From cte2 Union All Select * from cte2
Declare @SQL varchar(max) = Stuff((Select '','' + QuoteName(Item) From #Temp Where RN=0 Order by ColNr For XML Path('''')),1,1,'''')
Select @SQL = ''Select '' + @SQL + '' From (Select RN,Item,Value From #Temp ) A Pivot (max(Value) For [Item] in ('' + @SQL + '') ) p''
Exec(@SQL);
'
Exec(@SQL)
<强>返回强>
Updated NumberOfRecords
Updated NumberOfRecords
2017-03-22 597
2017-03-23 40
2017-03-20 228
2017-03-21 1404
只是一些评论
cte0是您的主要查询
cte1将获取初始查询的结果并添加行号
cte2将动态取消您的数据
为方便起见,将cte2的结果放入#temp表中(假设允许这样做)
然后我们执行动态数据透视
答案 1 :(得分:0)
使用列名联合静态查询。您必须将第二个查询的结果转换为varchar或nvarchar,因此它们与列名称的数据类型相同。
DECLARE @SQLSTATMENT nvarchar(1000)
SELECT @SQLSTATEMENT = '
SELECT
''DATEADDED'' AS [DATEADDED]
,''NUMBEROFRECORDS'' AS [NUMBEROFRECORDS]
SELECT
CAST(convert(date, DATEADDED) AS NVARCHAR(MAX)
,CAST(COUNT(1) AS NVARCHAR(MAX))
FROM
dbo.CONSTITUENT
GROUP BY
convert(date, DATEADDED)
ORDER BY
convert(date, DATEADDED) DESC
'
Exec (@SQLSTATEMENT);
说到这一点,您应该能够通过代码引用列名,而不必将它们添加到查询中。这样就可以保留结果集的数据类型。