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

在存储过程中,最好是简单地查询数据,或者构造一个查询然后执行它?为什么?

  •  2
  • pavanred  · 技术社区  · 14 年前

    首先,使用select查询,例如

    Select * from TableA where colA = 10 order by colA
    

    Declare @sqlstring varchar(100)
    Declare @sqlwhereclause varchar(100)
    Declare @sqlorderby varchar(100)
    
    Set @sqlstring = 'Select * from TableA '
    Set @sqlwhereclause = 'where colA = 10 '
    Set @sqlorderby = 'order by colA'
    
    Set @sqlstring = @sqlstring + @sqlwhereclause + @sqlorderby 
    exec @sqlstring
    

    现在,我知道两个都很好。但是,我提到的第二种方法有点烦人。

    我想知道哪个更好?有没有什么特别的理由让一个人使用一种方法而不是另一种方法?一种方法比另一种方法有什么好处吗?

    4 回复  |  直到 14 年前
        1
  •  5
  •   Oded    14 年前

    使用第一个。这将允许一个查询计划被正确地缓存,除了您应该使用SQL的方式之外。

    第二个是SQL注入攻击,除了其他问题。

    而且,你自己也注意到,维护的负担也更高。

        2
  •  4
  •   Klaus Byskov Pedersen    14 年前

    第二种方法有一个明显的缺点,即在编译时不进行语法检查。但是,它确实允许使用动态ORDERBY子句,而第一个子句不允许这样做。我建议您始终使用第一个示例,除非您有充分的理由使查询成为动态的。而且,正如@Oded已经指出的那样,如果您选择第二种方法,那么一定要防止sql注入。

        3
  •  1
  •   AJ.    14 年前

    考虑到这一点,有时您无法避免构造一个SQL语句,特别是当where子句和连接依赖于传入的参数时。根据我的经验,我发现为exec创建大型、可变连接/whered语句的存储过程正试图做太多的事情。在这种情况下,我建议你记住单一责任原则。

        4
  •  1
  •   dotariel    14 年前

    在存储过程中执行动态SQL会将使用存储过程的值降低为仅保存查询容器。存储过程最大的好处是,查询执行计划(一个非常昂贵的操作)在第一次执行过程时被编译并存储在内存中。这意味着过程的每个后续执行都绕过查询计划计算,直接跳到操作的数据检索部分。