我尝试实现一些动态SQL来创建游标作为简单SELECT查询的扩展。游标用作在SQL Server Management Studio中打印从SELECT返回的GROUPED值作为消息的方式(类似于数据的可视摘要)。这种方法的目的是半任务相关,一半有助于我理解如何开发动态SQL。代码如下:
DECLARE @Focus VARCHAR(10);
SET @Focus = 'Completed'; /* User input event focus {Started, Completed} */
DECLARE @PeriodStartDate DATE, @PeriodEndDate DATE;
SET @PeriodStartDate = '04/01/2014';
SET @PeriodEndDate = GETDATE();
DECLARE @sql VARCHAR(MAX);
SET @sql =
'SELECT ' +
'CASE DATEPART(M, ' + '[Event ' + CASE @Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) ' +
' WHEN 1 THEN ''January'' ' +
' WHEN 2 THEN ''February'' ' +
' WHEN 3 THEN ''March'' ' +
' WHEN 4 THEN ''April'' ' +
' WHEN 5 THEN ''May'' ' +
' WHEN 6 THEN ''June'' ' +
' WHEN 7 THEN ''July'' ' +
' WHEN 8 THEN ''August'' ' +
' WHEN 9 THEN ''September'' ' +
' WHEN 10 THEN ''October'' ' +
' WHEN 11 THEN ''November'' ' +
' WHEN 12 THEN ''December'' ' +
' END AS [Event ' + @Focus + ' Month], ' +
' COUNT([Unique ID]) AS [Number of Events] ' +
' FROM [udf_Events](' + @Focus + ', ' + CAST(@PeriodStartDate AS VARCHAR) + ', ' + CAST(@PeriodEndDate AS VARCHAR) + ') ' +
' GROUP BY ' +
' DATEPART(M, ' + '[Event ' + CASE @Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) ' +
' ORDER BY ' +
' DATEPART(M, ' + '[Event ' + CASE @Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) '
;
DECLARE Results CURSOR
FOR
SELECT
@sql;
我收到的错误讯息:
Msg 16924,Level 16,State 1,Line 71 Cursorfetch:Number of 在INTO列表中声明的变量必须与所选变量匹配 列。
通过使用EXEC(@sql)解决问题并尝试以SELECT语句执行查询(消除游标的复杂性),错误消息显示为:
无效的列名称“已完成”。
..这让我相信问题在于所选择的第一个字段中的CASE表达式。 udf_Events是一个带有三个参数的内联表值函数。除此之外,它还有[事件开始日期]和[事件结束日期]列,它们是光标在其上工作的值。
答案 0 :(得分:0)
尝试此操作...查询中缺少'
个
DECLARE @Focus VARCHAR(10);
SET @Focus = 'Completed'; /* User input event focus {Started, Completed} */
DECLARE @temp VARCHAR(500);
IF(@Focus = 'Completed')
SET @temp = '[Event End Date]'
ELSE
SET @temp = '[Event Start Date]'
DECLARE @PeriodStartDate DATE, @PeriodEndDate DATE;
SET @PeriodStartDate = '04/01/2014';
SET @PeriodEndDate = GETDATE();
DECLARE @sql VARCHAR(MAX);
SET @sql =
'SELECT ' +
'CASE DATEPART(M, ' + @temp + ')' +
' WHEN 1 THEN ''January'' ' +
' WHEN 2 THEN ''February'' ' +
' WHEN 3 THEN ''March'' ' +
' WHEN 4 THEN ''April'' ' +
' WHEN 5 THEN ''May'' ' +
' WHEN 6 THEN ''June'' ' +
' WHEN 7 THEN ''July'' ' +
' WHEN 8 THEN ''August'' ' +
' WHEN 9 THEN ''September'' ' +
' WHEN 10 THEN ''October'' ' +
' WHEN 11 THEN ''November'' ' +
' WHEN 12 THEN ''December'' ' +
' END AS [Event ' + @Focus + ' Month], ' +
' COUNT([Unique ID]) AS [Number of Events] ' +
' FROM [udf_Events](''' + @Focus + ''', ''' + CAST(@PeriodStartDate AS VARCHAR) + ''', ''' + CAST(@PeriodEndDate AS VARCHAR) + ''') ' +
' GROUP BY ' +
' DATEPART(M, ' + @temp + ')' +
' ORDER BY ' +
' DATEPART(M, ' + @temp + ')';
print @sql
答案 1 :(得分:0)
您没有引用udf_Events
来电中的日期,因此您最终会
[udf_Events](Completed, 2014-04-01, 2014-09-19)
而不是
[udf_Events](Completed, '2014-04-01', '2014-09-19')
修复方法是更改行
' FROM [udf_Events](' + @Focus + ', ' + CAST(@PeriodStartDate AS VARCHAR) + ', ' + CAST(@PeriodEndDate AS VARCHAR) + ') ' +
到
' FROM [udf_Events](' + @Focus + ', ''' + CAST(@PeriodStartDate AS VARCHAR) + ''', ''' + CAST(@PeriodEndDate AS VARCHAR) + ''') ' +
也就是说,如果udf_Events
的参数为datetimes
,那么我会考虑将格式更改为YYYYMMDD
,因为这是明确的。为此,您可以使用CONVERT(char(8), <date>, 112)
,其中<date>
是要转换的日期。
即:
' FROM [udf_Events](' + @Focus + ', ''' + CONVERT(char(8), @PeriodStartDate, 112) + ''', ''' + CONVERT(char(8), @PeriodEndDate, 112) + ''') ' +