使用SQL过滤存储过程的结果

Ben*_*ack 32 sql t-sql sql-server stored-procedures sql-server-2005

我已经查看了与此问题相关的Stack Overflow上的其他问题,但他们似乎都没有清楚地回答这个问题.

我们有一个名为sp_who2的系统存储过程,它返回服务器上所有正在运行的进程的信息结果集.我想过滤存储过程返回的数据; 从概念上讲,我可能会这样做:

SELECT * FROM sp_who2
WHERE login='bmccormack'
Run Code Online (Sandbox Code Playgroud)

但是,这种方法不起作用.实现查询存储过程的返回数据的目标的好方法是什么,优选地不必查看原始存储过程的代码并对其进行修改.

Pat*_*her 33

没有好方法可以做到这一点.这是存储过程的限制.你的选择是:

  1. 将过程切换到用户定义的功能.在全世界,今天,人们正在制作应该是功能的存储过程.这是一个教育问题.你的情况是一个很好的例子.如果您的程序是UDF,那么您可以执行以下操作,正如您直觉地认为您应该能够:

    SELECT * FROM udf_who2()
    WHERE login='bmccormack'
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果你真的无法触摸你的程序,并且必须在sql中完成,那么你必须得到时髦.制作另一个存储过程来包装原始过程.在新过程中调用现有过程并将值放入临时表中,然后使用所需的过滤器对该表运行查询,并将结果返回给外部世界.

从SQL Server 2005开始,用户定义的函数就是封装数据检索的方式.存储过程以及视图是在特定情况下使用的专用工具.它们在正确的时间都非常方便,但不是第一选择.有些人可能会认为上面的例子(A)得到了函数的所有结果,然后(B)对结果集进行了过滤,就像子查询一样. 事实并非如此.SQL server 2005+优化了该查询; 如果有索引login,则在查询执行计划中看不到表扫描; 效率很高.

编辑:我应该补充一点,UDF的内部结构类似于SP的内部结构.如果它想要避免使用SP 的逻辑,您仍然可以将其更改为函数.好几次我都采用了我不想理解的大型,可怕的程序代码,并成功将其转移到了一个函数中.除了返回结果之外,唯一的问题是如果程序修改了任何内容; UDF无法修改数据库中的数据.


小智 15

过滤临时表是可能的方法.

-- Create tmp table from sp_who results
CREATE TABLE #TmpWho
(spid INT, ecid INT, status VARCHAR(150), loginame VARCHAR(150),
hostname VARCHAR(150), blk INT, dbname VARCHAR(150), cmd VARCHAR(150), request_id INT)
INSERT INTO #TmpWho
EXEC sp_who

-- filter temp table where spid is 52
SELECT * FROM #TmpWho
WHERE spid = 52

DROP TABLE #TmpWho
Run Code Online (Sandbox Code Playgroud)


bry*_*ker 12

您可以执行此操作OPENROWSET(),但涉及一些安全/性能问题.

SELECT * 
FROM OPENROWSET ('SQLOLEDB', 'Server=(local);TRUSTED_CONNECTION=YES;', 'exec mystoredproc')
Run Code Online (Sandbox Code Playgroud)

传统上,将它添加到临时变量/表将起作用.