我必须为学校项目编码一个数据库系统。我们必须确保我们的程序包含以下内容:
据我了解,聚合的SQL函数包括AVG,COUNT,MIN,MAX和SUM。跨表参数化SQL是否仅意味着将SQL作为参数传递?
答案 0 :(得分:0)
这是一个跨表参数化查询(SQL Server样式):
SELECT *
FROM
Students s
INNER JOIN
Grades g
ON
s.Id = g.StudentId
WHERE
s.LastName LIKE @lastname
这意味着您必须将两个或多个表连接在一起,并使用@parameter
限制查询输出的行,而不是硬编码值(可能通过字符串连接)
WHERE Lastname LIKE 'Smith%' --hardcoded value - wrong
以及在C#中使用它的示例:
string sql = @"SELECT *
FROM
Students s
INNER JOIN
Grades g
ON
s.Id = g.StudentId
WHERE
s.LastName LIKE @lastname";
SqlCommand cmd = new SqlCommand(sql, connectionString);
cmd.Parameters.AddWithValue("@lastname", "Smith%"); //correct use of parameterisation
cmd.Parameters.AddWithValue("@lastname", _lastnameTextbox.Text); //or let's go a step further and use the value the user typed in
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable():
da.Fill(dt);
不要这样做(在您的所有专业编程生涯中,永远不要这样做):
string sql = @"SELECT *
FROM
Students s
INNER JOIN
Grades g
ON
s.Id = g.StudentId
WHERE
s.LastName LIKE '" + lastnameTextBox.Text + "'"; //INCORRECT use of string concatenation - this is NOT parameterising
出于您的学校为什么不鼓励您这样做的原因,请阅读http://bobby-tables.com或Google SQL Injection Hacking
聚合查询将几行分组为一列:
SELECT s.Firstname, s.Lastname, COUNT(*) as ExamsSat, AVG(g.PercentScore) AverageScore, MAX(g.Grade) as WorstGrade
FROM
Students s
INNER JOIN
Grades g
ON
s.Id = g.StudentId
GROUP BY
s.FirstName,
s.LastName;
假设一个学生在“学生”中有一个记录,在“成绩”中有3个记录,例如:
StudentID, PercentScore, Grade
1, 90, A
1, 75, B
7, 66, C
然后在不进行任何汇总(分组依据)的情况下将student和成绩表结合在一起将为我们提供有用的详细信息:
--SELECT * FROM Student s INNER JOIN Grades g ON g.StudentID = s.ID
1, John, Smith, 1, 90, A
1, John, Smith, 1, 75, B
1, John, Smith, 1, 66, C
但是,如果我们想要那个平均分数或最差成绩呢?使用GROUP BY运行查询,将为学生提供一行,并带有汇总列:
John, Smith, 3, 77, C
详细信息中的那3行折叠为1行。 GROUP BY位中命名的列将决定行的唯一组合是什么。我们的详细信息行有3行,其中重复了“ John Smith”。那将成为1行。所有其他列都必须是某种汇总/分组,例如COUNT,MAX,AVG,MIN等
请记住,字母上的MAX考虑例如C大于A-在学术上不是这样,因此A成绩按字母顺序最低,但成就最高。 (90 + 75 + 66)/ 3 = 77-这是AVG执行的操作