0

我在一个非常大的项目中使用 SQL Server 2000 受到限制。对于一个模块,我必须创建 3 到 10 个存储过程。为了使其易于管理,我正在编写一个存储过程来根据条件返回不同的 SQL 查询,例如:

If @QueryId = 'SelAllEmp'
   Select EmpId,EmpName from EMP 
ELSE IF  @QueryId = 'SelEmpById'
   Select EmpId,EmpName from EMP where EmpId= @EmpId
ELSE IF @QueryId = 'EMPDept'
   Select EmpId, DeptId, DeptName from EMPDept
......................................

我的问题是,使用这种技术是否有任何隐藏的后果或影响?

4

2 回答 2

2

我认为您处理此问题的方式根本无法管理。对于您在问题中显示的情况,您应该努力进行单个查询。让客户决定他们是否会使用该DeptName列 - 客户可以选择忽略它,并且知道这样做是因为它必须传递EmpDept参数。如果您的客户可以忽略该列,那么您的三个查询可以成为一个:

SELECT EmpId, EmpName, DeptName
  FROM dbo.EMP 
  WHERE EmpId = CASE 
    WHEN @QueryId = 'SelEmpById' THEN @EmpId ELSE EmpId END;

此查询解决了您的所有三个条件。为避免陷入糟糕的计划,您可以将OPTION (RECOMPILE)语句添加到 WITH RECOMPILE过程中。是的,这可能会导致开销(不像 Joon 说的那么糟糕),但是我每次都会进行一些编译,而不是每隔一天就陷入一个可怕的计划。默认情况下,SQL Server 2000 无法优化单个存储过程的所有路径。

另一种选择是使用动态 SQL 构建您需要的查询。这可能会导致计划缓存膨胀,但如果频繁使用所有选项,它应该不会太糟糕。您可以通过使用服务器设置来避免这可能导致计划缓存膨胀的问题。optimize for ad hoc workloads

Erland Sommarskog 的两篇非常有价值的读物:

基本上,不要害怕动态 SQL,但要注意潜在的问题。

抱歉,由于我的回答是针对较新版本的 SQL Server 的,所以回来并进行了编辑。很难记住人们出于某种原因仍在使用 SQL Server 2000。

于 2012-07-24T12:39:54.453 回答
0

当存储过程超过一定的复杂性时,无论何时从客户端调用它都会重新编译。

这会给服务器带来开销,并且在繁忙的应用程序中,如果这种情况发生得足够多,可能会导致整体性能下降。

这是遵循这种技术的一个潜在负面后果。

此外,您的结果集会根据存储过程的输入而更改。这可能会破坏期望某个字段存在或不存在的客户。

于 2012-07-24T11:56:21.803 回答