我有以下存储过程,如果我在我们的SQL分析器上执行它,它会返回记录没有问题。但是,如果我通过ASP.NET(我正在使用EntitySpace对象)执行此操作以将此查询生成到数据表中,并且它说:“Cursorfetch:在INTO列表中声明的变量数必须与所选列的变量数匹配。”
我和EntitySpace团队讨论了这个问题,他们说这是查询问题吗?!?!有什么想法吗?我们坚持这个问题以及任何有益的指导或提示。
我们使用的环境: .NET 4 EntitySpace 2010 SQL Server 2005数据库
ALTER PROCEDURE [dbo].[rpt_CPRRespondListReport]
(
@SurveyID INT
)
AS
BEGIN
SET NOCOUNT ON;
SET FMTONLY OFF;
DECLARE @SID INT;
SELECT @SID = sid
FROM lime_Surveys
WHERE sid = @SurveyID
IF (@SID > 1)
BEGIN
DECLARE @T TABLE
(
RecID INT,
RecID2 INT,
RecID3 INT,
RecID4 INT,
FirstName VARCHAR(40),
LastName VARCHAR(40),
Email VARCHAR(320),
QuestionName VARCHAR(100),
QuestionValue1 VARCHAR(5),
QuestionValue2 VARCHAR(5),
QuestionValue3 VARCHAR(1000),
QuestionValue4 VARCHAR(5)
);
DECLARE @ColumnNameRow VARCHAR(MAX);
DECLARE @Column_name VARCHAR(32);
DECLARE @sqlstatement1 NVARCHAR(MAX)
SET @sqlstatement1 = 'DECLARE QuestionCursor CURSOR FOR ' +
'SELECT column_name ' +
'FROM information_schema.columns (NOLOCK) ' +
'WHERE table_name = ''lime_survey_' + CAST(@SurveyID AS VARCHAR) + ''' AND Ordinal_position >= 10 ' +
'ORDER BY ordinal_position ASC'
EXEC sp_executesql @sqlstatement1
SET @ColumnNameRow = '';
OPEN QuestionCursor
FETCH NEXT FROM QuestionCursor
INTO @Column_name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @ColumnNameRow = @ColumnNameRow + '[' + @Column_Name + ']' + ', '
FETCH NEXT
FROM QuestionCursor
INTO @Column_name
END
SET @ColumnNameRow = SUBSTRING(@ColumnNameRow, 1, LEN(@ColumnNameRow) - 1);
CLOSE QuestionCursor
DEALLOCATE QuestionCursor
DECLARE @tid INT;
DECLARE @FirstName VARCHAR(40);
DECLARE @LastName VARCHAR(40);
DECLARE @Email VARCHAR(320);
DECLARE @Q010101 VARCHAR(5);
DECLARE @Q010102 VARCHAR(5);
DECLARE @Q010103 VARCHAR(1000);
DECLARE @Q010201 VARCHAR(5);
DECLARE @Q010202 VARCHAR(5);
DECLARE @Q010203 VARCHAR(1000);
DECLARE @Q010301 VARCHAR(5);
DECLARE @Q010302 VARCHAR(5);
DECLARE @Q010303 VARCHAR(1000);
DECLARE @Q010401 VARCHAR(5);
DECLARE @Q010402 VARCHAR(5);
DECLARE @Q010403 VARCHAR(1000);
DECLARE @Q010501 VARCHAR(5);
DECLARE @Q010502 VARCHAR(5);
DECLARE @Q010503 VARCHAR(1000);
DECLARE @Q010601 VARCHAR(5);
DECLARE @Q010602 VARCHAR(5);
DECLARE @Q010603 VARCHAR(1000);
DECLARE @Q010701 VARCHAR(5);
DECLARE @Q010702 VARCHAR(5);
DECLARE @Q010703 VARCHAR(1000);
DECLARE @Q010801 VARCHAR(5);
DECLARE @Q010802 VARCHAR(5);
DECLARE @Q010803 VARCHAR(1000);
DECLARE @Q010901 VARCHAR(5);
DECLARE @Q010902 VARCHAR(5);
DECLARE @Q010903 VARCHAR(1000);
DECLARE @Q011001 VARCHAR(5);
DECLARE @Q011002 VARCHAR(5);
DECLARE @Q011003 VARCHAR(1000);
DECLARE @Q011101 VARCHAR(5);
DECLARE @Q011102 VARCHAR(5);
DECLARE @Q011103 VARCHAR(1000);
DECLARE @Q011201 VARCHAR(5);
DECLARE @Q011202 VARCHAR(5);
DECLARE @Q011203 VARCHAR(1000);
DECLARE @Q011301 VARCHAR(5);
DECLARE @Q011303 VARCHAR(1000);
DECLARE @sqlstatement2 NVARCHAR(MAX)
SET @sqlstatement2 = 'DECLARE SURVEY_RESULT_CURSOR CURSOR FOR
SELECT tid, FirstName, LastName, Email, ' + @ColumnNameRow + '
FROM dbo.lime_tokens_' + CAST(@SurveyID AS VARCHAR) + ' a (NOLOCK) INNER JOIN lime_survey_' + CAST(@SurveyID AS VARCHAR) + ' b (NOLOCK) ON a.token = b.token
where Completed IS NOT NULL'
EXEC sp_executesql @sqlstatement2
OPEN SURVEY_RESULT_CURSOR
FETCH NEXT FROM SURVEY_RESULT_CURSOR
INTO @tid, @FirstName, @LastName, @Email,
@Q010101, @Q010102, @Q010103, @Q010201, @Q010202, @Q010203, @Q010301, @Q010302, @Q010303, @Q010401, @Q010402, @Q010403,
@Q010501, @Q010502, @Q010503, @Q010601, @Q010602, @Q010603, @Q010701, @Q010702, @Q010703, @Q010801, @Q010802, @Q010803,
@Q010901, @Q010902, @Q010903, @Q011001, @Q011002, @Q011003, @Q011101, @Q011102, @Q011103, @Q011201, @Q011202, @Q011203,
@Q011301, @Q011303
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @T(RecID, RecID2, RecID3, RecID4, FirstName, LastName, Email, QuestionName, QuestionValue1, QuestionValue2, QuestionValue3)
SELECT @tid, 1, 1, 1, @FirstName, @LastName, @Email, 'Mobile Voice Coverage', @Q010101, @Q010102, @Q010103
UNION
SELECT @tid, 1, 2, 1, @FirstName, @LastName, @Email, 'Mobile Data Coverage', @Q010201, @Q010202, @Q010203
UNION
SELECT @tid, 1, 3, 1, @FirstName, @LastName, @Email, 'Mobile Voice Costs', @Q010301, @Q010302, @Q010303
UNION
SELECT @tid, 1, 4, 1, @FirstName, @LastName, @Email, 'Mobile Data Costs', @Q010401, @Q010402, @Q010403
UNION
SELECT @tid, 1, 5, 1, @FirstName, @LastName, @Email, 'International Roaming Costs', @Q010501, @Q010502, @Q010503
UNION
SELECT @tid, 1, 6, 1, @FirstName, @LastName, @Email, 'Handset Quality', @Q010601, @Q010602, @Q010603
UNION
SELECT @tid, 1, 7, 1, @FirstName, @LastName, @Email, 'Mobile Capped Plans', @Q010701, @Q010702, @Q010703
UNION
SELECT @tid, 1, 8, 1, @FirstName, @LastName, @Email, 'Message Bank / Voicemail', @Q010801, @Q010802, @Q010803
UNION
SELECT @tid, 1, 9, 1, @FirstName, @LastName, @Email, 'SMS', @Q010901, @Q010902, @Q010903
UNION
SELECT @tid, 1, 10, 1, @FirstName, @LastName, @Email, 'Mobile Internet / Email Account', @Q011001, @Q011002, @Q011003
UNION
SELECT @tid, 1, 11, 1, @FirstName, @LastName, @Email, 'Access to our office intranet', @Q011101, @Q011102, @Q011103
UNION
SELECT @tid, 1, 12, 1, @FirstName, @LastName, @Email, 'Account Management', @Q011201, @Q011202, @Q011203
UNION
SELECT @tid, 1, 13, 3, @FirstName, @LastName, @Email, 'Current Provider', @Q011301, null, @Q011303
FETCH NEXT FROM SURVEY_RESULT_CURSOR
INTO @tid, @FirstName, @LastName, @Email,
@Q010101, @Q010102, @Q010103, @Q010201, @Q010202, @Q010203, @Q010301, @Q010302, @Q010303, @Q010401, @Q010402, @Q010403,
@Q010501, @Q010502, @Q010503, @Q010601, @Q010602, @Q010603, @Q010701, @Q010702, @Q010703, @Q010801, @Q010802, @Q010803,
@Q010901, @Q010902, @Q010903, @Q011001, @Q011002, @Q011003, @Q011101, @Q011102, @Q011103, @Q011201, @Q011202, @Q011203,
@Q011301, @Q011303
END
CLOSE SURVEY_RESULT_CURSOR
DEALLOCATE SURVEY_RESULT_CURSOR
SELECT RecID, RecID2, RecID3, RecID4, FirstName, LastName, Email, QuestionName, b.Title AS QuestionValue1,
b2.Title AS QuestionValue2, QuestionValue3
FROM @T a LEFT OUTER JOIN lime_labels b (NOLOCK) ON a.QuestionValue1 = b.Code
LEFT OUTER JOIN lime_labels b2 (NOLOCK) ON a.QuestionValue2 = b2.Code
ORDER BY RecID ASC, RecID2 ASC, RecID3 ASC
END
END
答案 0 :(得分:2)
你的问题在于光标SURVEY_RESULT_CURSOR
是用可变数量的列定义的
'DECLARE SURVEY_RESULT_CURSOR CURSOR FOR
SELECT tid, FirstName, LastName, Email, ' + @ColumnNameRow + '
而FETCH .. INTO子句有一个要插入
的FIXED列列表FETCH NEXT FROM SURVEY_RESULT_CURSOR
INTO @tid, @FirstName, @LastName, @Email,
@Q010101, @Q010102, @Q010103, @Q010201, @Q010202, @Q010203, @Q010301, @Q010302, @Q010303, @Q010401, @Q010402, @Q010403,
@Q010501, @Q010502, @Q010503, @Q010601, @Q010602, @Q010603, @Q010701, @Q010702, @Q010703, @Q010801, @Q010802, @Q010803,
@Q010901, @Q010902, @Q010903, @Q011001, @Q011002, @Q011003, @Q011101, @Q011102, @Q011103, @Q011201, @Q011202, @Q011203,
@Q011301, @Q011303
当这两个计数不匹配时,您将收到该错误。
考虑它是否应该是静态计数(甚至不需要QuestionCursor)或重新考虑你的方法(可能是动态SQL)
编辑:在两个条件下,您仍然可以将抓取到SURVEY_RESULT_CURSOR
修复的变量列表中
对于2,不难计算有多少逗号(假设列名没有逗号),然后根据需要追加cast(NULL as varchar(5)) dummcol1, ..
个。 varchar(5)到varvar的@var(1000)就可以了。
计算逗号:
set @commacount = len(@ColumnNameRow) - len(replace(@ColumnNameRow,',',''))