Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如果在存储过程中放入冗长的SQL select,效率是否会提高?_Sql Server_Sql Server 2012 - Fatal编程技术网

Sql server 如果在存储过程中放入冗长的SQL select,效率是否会提高?

Sql server 如果在存储过程中放入冗长的SQL select,效率是否会提高?,sql-server,sql-server-2012,Sql Server,Sql Server 2012,我有以下SQL Server 2012查询: var sql = @"Select question.QuestionUId FROM Objective, ObjectiveDetail, ObjectiveTopic, Problem, Question where objective.examId

我有以下SQL Server 2012查询:

var sql = @"Select question.QuestionUId
            FROM Objective,
                 ObjectiveDetail,
                   ObjectiveTopic,
                   Problem,
                   Question
            where objective.examId = 1
            and objective.objectiveId = objectiveDetail.objectiveId
            and objectiveDetail.ObjectiveDetailId = ObjectiveTopic.ObjectiveDetailId
            and objectiveTopic.SubTopicId = Problem.SubTopicId
            and problem.ProblemId = question.ProblemId";

            var a = db.Database.SqlQuery<string>(sql).ToList(); 
有人能帮我解释一下,把这个放进一个 存储过程,如果是这样的话,我怎样才能做到这一点,然后从我的C代码调用它。是的 向我建议,如果它在存储过程中,那么它将运行得更多
效率很高,因为它不会经常重新编译。是这样吗

是的,有。首先,预编译存储过程并将其存储在数据库中。通过预编译,数据库引擎可以更高效地执行它,因为不需要动态编译。此外,还可以添加数据库优化以支持预编译过程。存储过程还允许将业务逻辑封装在数据库中

如果您决定去存储过程路由,那么考虑以下内容:

首先,您需要创建一个存储过程来封装现有的SQL查询

CREATE PROCEDURE ListQuestionIds
    @ExamId int
AS
BEGIN

    SELECT Question.QuestionUId
    FROM Objective
    INNER JOIN ObjectiveDetail
        ON ( Objective.objectiveId = ObjectiveDetail.objectiveId )
    INNER JOIN ObjectiveTopic
        ON ( ObjectiveDetail.ObjectiveDetailId = ObjectiveTopic.ObjectiveDetailId )
    INNER JOIN Problem
        ON ( ObjectiveTopic.SubTopicId = Problem.SubTopicId )
    INNER JOIN Question
        ON ( Problem.ProblemId = Question.ProblemId )
    WHERE Objective.examId = @ExamId;

END;
请确保过程目标、问题等调用的表具有所有相关的主键和索引,以提高查询的性能

接下来,需要从C代码中调用该存储过程。一种方法(但决不是唯一的方法)是使用SqlConnection对象创建到数据库的连接,然后通过SqlCommand对象执行过程

我建议您查看一些主题示例。但这方面的一个简单示例可能如下所示:

string connectionString = "your_connection_string";

using (var con = new SqlConnection(connectionString))
{
    using (var cmd = new SqlCommand("ListQuestionIds", con)) {

        cmd.CommandType = CommandType.StoredProcedure

        cmd.Parameters.Add(new SqlParameter("@ExamId", examId))

        con.Open();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                // Loop through the returned SqlDataReader object (aka. rdr) and
                // then evaluate & process the returned question id value(s) here
            }
        }
    }
}
请注意,此示例代码并不有意包含任何错误处理。我把这件事留给你来集成到你的应用程序中

最后,仅供参考。。。许多更现代的ORM(例如Entity Framework、NHibernate等)允许您从C代码执行类似于查询的存储过程,而无需显式存储过程。如果您已经在应用程序中使用ORM,那么您可能希望完全放弃存储过程。无论你决定做什么,在你身边做一点调查将帮助你做出明智的决定


我希望这能帮助你开始。祝你好运。

是的,SP是预编译的。SP有一点好处,它以编译状态存储,但通常编译的开销很小,特别是对于大型数据集。e、 g.运行时间为2小时,编译时间为0.000001秒。哇,我可以多眨眼一次@xQbert-您的论点不直接适用。可以使用无存储过程的n层设计。此外,SQL注入仍然可以通过存储过程进行,具体取决于它的编写方式。使用参数化查询是避免SQL注入的最佳方法。@phaedra以及如何使用SP进行SQL注入?@phaedra可以,但这是他们将传递给SP的参数转换为动态SQL的目的。