如何使用 SqlDataReader 获取存储过程返回的分组数据
本文关键字:数据 返回 存储过程 何使用 SqlDataReader 获取 | 更新日期: 2023-09-27 18:32:49
我有一个由下式定义的 sproc
CREATE PROCEDURE GetQuestionsGroupedBySection
@survey_id INT
AS
SELECT S.title, Q.qtext
FROM Sections AS S INNER JOIN Questions AS Q
ON S.id = Q.section_id
WHERE S.survey_id = @survey_id
GROUP BY S.title;
其中相关表由
CREATE TABLE Questions (
id INT IDENTITY(1,1),
section_id INT,
qtext NVARCHAR(300) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (section_id) REFERENCES Sections(id) ON DELETE CASCADE
);
和
CREATE TABLE Sections (
id INT IDENTITY(1,1),
title NVARCHAR(200) NOT NULL,
survey_id INT,
PRIMARY KEY (id),
FOREIGN KEY (survey_id) REFERENCES Surveys(id) ON DELETE CASCADE
);
现在我尝试从我的服务器端代码中调用它,以便在类型元素的List
中获取分组
public class QuestionsBySection
{
public string SectionTitle { get; set; }
public List<string> SecionQuestions;
}
(或者有更好的数据结构可以使用吗?我拥有的是
public List<QuestionsBySection> GetQuestionsAndSection (int survid)
{
// survid: survey id
List<QuestionsBySection> AllQuestions = new List<QuestionsBySection>();
using (SqlCommand cmd = new SqlCommand("GetQuestionsGroupedBySection", this._Conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@survey_id", survid);
this._Conn.Open();
using ( SqlDataReader dataReader = cmd.ExecuteReader() )
{
while ( dataReader.Read() )
{
// ...
}
}
this._Conn.Close();
}
return AllQuestions;
}
但我不确定如何填写// ...
.有什么提示吗?
Sql 分组依据是错误的
结果中有 2 列,但组中只有 1 列。您可以将第二列添加为按字段分组,也可以使用聚合(例如 min() 或 max())。
SELECT S.title, qtext=max(Q.qtext)
FROM .....
数据读取器
只需使用字段位置作为 GetString 的索引参数:
var sTitle = dataReader.GetString(0);
var sQuestion = dataReader.GetString(1);
SQL
查询在 SQL Server 中无效;使用 group by 子句时,所有选定的字段都必须包含在 group by 子句中,或者是聚合字段。根据您的预期结果,有几种方法可以返回QuestionsBySection
集合。
一种选择是返回平展的结果集,然后在应用层上聚合。
SProc 应删除 group by
条款:
SELECT S.title, Q.qtext
FROM Sections AS S INNER JOIN Questions AS Q
ON S.id = Q.section_id
WHERE S.survey_id = @survey_id
检索时,需要评估每一行以查看标题是否已使用:
var questions = new List<QuestionsBySection>();
// create sql connection
// execute command
while (dataReader.Read())
{
string title = dataReader.GetString("title");
string question = dataReader.GetString("qtext");
QuestionsBySection qbs = questions.FirstOrDefault(x => x.SectionTitle.Equals(title , StringComparison.OrdinalIgnoreCase))
if (qbs != null)
{
qbs.SecionQuestions.Add(question);
continue;
}
qbs = new QuestionsBySection
{
SectionTitle = title,
SecionQuestions = new List<string>{ question }
}
questions.Add(qbs);
}
还有其他几种方法可以实现结果,但这应该可以让您更好地了解如何聚合结果。