代码之家  ›  专栏  ›  技术社区  ›  tster

一次往返执行多个sql命令

  •  28
  • tster  · 技术社区  · 15 年前

    我正在构建一个应用程序,我想将多个查询批处理成一次数据库往返。例如,假设一个页面需要显示用户列表、组列表和权限列表。

    所以我已经存储了proc(或者只是简单的sql命令,比如“select*fromsusers”),我想执行其中的三个。但是,要填充这一页,我必须进行3次往返旅行。

    现在我可以编写一个存储过程(“getusersteamsandpmissions”)或执行一个sql命令“select*fromsusers;exec getteams;select*frompmissions”。

    但我想知道是否有更好的方法来指定在一次往返中执行3个操作。好处包括更容易进行单元测试,并允许数据库引擎并行化查询。

    我正在使用C 3.5和SQL Server 2008。

    6 回复  |  直到 14 年前
        1
  •  8
  •   Community CDub    8 年前

    您提到的单个多部分命令和存储过程选项是两个选项。你不能这样做,他们是“并行”的数据库。但是,这两种选择都会导致 单程往返 ,所以你在那里很好。没有办法让他们更有效率。在sql server 2005以后的版本中,完全参数化的多部分命令非常有效。

    编辑 :添加有关为什么要塞进单个呼叫的信息。

    虽然你不想太在意减少通话,但是 可以 这是正当的理由。

    • 我曾经被限制在主机上一个糟糕的odbc驱动程序上,每次调用都有1.2秒的开销!我是认真的。有时我会临时抱佛脚 额外的 我的数据库通话。不漂亮。
    • 您还可能会发现,您必须在某个地方配置SQL查询,而不能只进行3次调用:必须是一次调用。不应该是那样,糟糕的设计,但确实是这样。你做你该做的!
    • 当然,有时在存储过程中封装多个步骤是非常好的。通常不是为了节省往返时间,而是为了更紧密的事务,获取新记录的id,限制权限,提供封装,等等。( But please don't start using stored procedures all the time. )
        2
  •  36
  •   Darin Dimitrov    15 年前

    有点像 this . 这个例子可能不是很好,因为它不能正确地处理对象,但你得到了这个想法。以下是清理版本:

    using (var connection = new SqlConnection(ConnectionString))
    using (var command = connection.CreateCommand())
    {
        connection.Open();
        command.CommandText = "select id from test1; select id from test2";
        using (var reader = command.ExecuteReader())
        {
            do
            {
                while (reader.Read())
                {
                    Console.WriteLine(reader.GetInt32(0));
                }
                Console.WriteLine("--next command--");
            } while (reader.NextResult());
    
        }
    }
    
        3
  •  2
  •   Remus Rusanu    15 年前

    做一次往返对三次确实会更缺乏效率。问题是这件事值得不值得。整个ado.net和c 3.5工具集和框架都反对您的尝试。tableadapters、linq2sql、ef,所有这些都喜欢处理简单的one call==one resultset语义。因此,您可能会通过尝试使框架屈服而失去一些重要的生产力。

    我想说的是,除非你有一些严重的测量表明你需要减少往返的次数,否则弃权。如果你 最终需要这样做,然后使用存储过程至少给出一种api类型的语义。

    但如果你的问题真的是你发布的(如选择 全部的 用户, 全部的 团队和 全部的 权限)那么你显然有更大的鱼炸之前,减少往返…首先减少结果集。

        4
  •  1
  •   Shimmy Weitzhandler 500 - Internal Server Error    14 年前

    我这 this 链接可能会有帮助。

    考虑使用至少相同的连接打开;根据它所说的 here 在实体框架中,打开连接几乎是性能成本的最高领导者。

        5
  •  0
  •   Justin    15 年前

    首先,3次往返并不是什么大事。如果你在说 三百 往返旅行那将是另一回事,但仅3次往返,我将谴责这一点,明确地说,这是一个过早优化的情况。

    也就是说,我这样做的方式可能是使用sql执行3个存储过程:

    exec dbo.p_myproc_1 @param_1 = @in_param_1, @param_2 = @in_param_2
    exec dbo.p_myproc_2
    exec dbo.p_myproc_3
    

    然后,可以像直接执行多个行集一样遍历返回的结果集。

        6
  •  0
  •   Earlz    15 年前

    建一个临时表?将所有结果插入临时表,然后 select * from @temp-table

    在,

    @temptable=....
    select @temptable.field=mytable.field from mytable
    select @temptable.field2=mytable2.field2 from mytable2
    

    等。。。只访问一次数据库,但我不确定它是否更有效。

    推荐文章