【问题标题】:SELECT specific columns from EXEC stored procedure从 EXEC 存储过程中选择特定列
【发布时间】:2013-07-25 16:02:10
【问题描述】:

我在尝试从存储过程的 EXEC 语句中 SELECT 特定列时遇到问题。我正在尝试找到存储过程返回的COUNT(*),我正在成功地使用它:

INSERT INTO #temp
EXEC dbo.my_sp
SET @count = (SELECT COUNT(*) FROM #temp)
DELETE FROM #temp

但是,这仅在返回的列与表列特别匹配时才有效,并且由于我试图查找许多不同存储过程的计数(每个存储过程返回不同的列),如果不创建新的列,我将无法使用此方法每个存储过程的表。

有没有办法可以SELECT EXEC dbo.my_sp 中的特定列?

【问题讨论】:

    标签: sql sql-server sql-server-2008 select stored-procedures


    【解决方案1】:

    创建到本地实例的环回链接服务器,确保启用数据访问。假设您有一个名为 YourServer\SQL2008 的本地命名实例:

    USE [master];
    GO
    EXEC sp_addlinkedserver 
      @server     = N'LoopbackLocal', 
      @srvproduct = N'',
      @provider   = N'SQLNCLI', 
      @datasrc    = N'.\SQL2008', 
      @catalog    = N'tempdb';
    GO
    
    EXEC sp_serveroption 
      @server   = N'LoopbackLocal', 
      @optname  = N'collation compatible', 
      @optvalue = N'true';
    GO
    
    EXEC sp_serveroption 
      @server   = N'LoopbackLocal', 
      @optname  = N'data access', 
      @optvalue = N'true';
    GO
    
    EXEC sp_addlinkedsrvlogin 
      @rmtsrvname = N'LoopbackLocal', 
      @locallogin = NULL , 
      @useself    = N'True';
    GO
    -- you may need to configure other security here
    

    然后您可以使用OPENQUERY 来运行存储过程,就好像它是一个即席查询一样。

    SELECT COUNT(*)
      FROM OPENQUERY
      (
        LoopbackLocal, 
        'EXEC dbo.my_sp'
      ) AS y;
    

    现在,如果dbo.my_sp 首先将信息转储到#temp 表中,您就会遇到问题,因为它不再是OPENQUERY 可以处理的代码块。例如,如果您尝试以这种方式执行 sp_who2,至少在 SQL Server 2012 中,您将收到来自 sp_describe_first_result_set 的错误,其中 OPENQUERY 已更改为使用(所以也许现在这对您有用,我不'没有 2008 年要测试,但总有一天会成为问题):

    消息 11526,级别 16,状态 1,过程 sp_describe_first_result_set,第 1 行
    无法确定元数据,因为 ... 使用临时表。

    但是,如果您要经常这样做,为什么不制作专门的存储过程(或向这些存储过程添加选项)以便只返回一个计数?

    【讨论】:

    • 我确实看到了这个工作,但是我没有执行这个任务的权限(我不在家工作,所以很遗憾我无法修复/更改)。此外,我不会经常执行该任务,因此如果可能的话,我想将该过程保留在一个简单的存储过程中。
    • 当过程使用临时表时,有什么方法可以使这项工作? SQL 2012 给出了关于 sp_describe_first_result_set 使用临时表存储的 procs 失败的错误。编辑:没关系,刚刚看到你的编辑!
    • @KevinDahl 我不这么认为,似乎OPENQUERY 已更改为在内部使用这些新程序,这是它们的已知限制(OPENROWSET() 以同样的方式失败)。
    【解决方案2】:

    @@ROWCOUNT 对你有用吗?

    if OBJECT_ID('SomeProc') is null
        exec ('create procedure dbo.SomeProc as select 1 as SomeValue union all select 2 as SomeValue;')
    
    exec dbo.SomeProc
    
    Select @@ROWCOUNT as RowsAffected
    

    http://technet.microsoft.com/en-us/library/ms187316(v=sql.105).aspx

    【讨论】:

    • 这对我有用。但是现在每个exec 调用实际上都在返回数据,这是以前没有的。我正在使用EXEC dbo.my_sp1 SET @value1= (SELECT @@ROWCOUNT) EXEC dbo.my_sp2 SET @value2 = (SELECT @@ROWCOUNT) SELECT @value1, @value2 我只想要两个值,而不是来自exec的值
    • 存储过程的最终结果是什么?您是否在某事中使用返回的数据?
    • 它返回我需要用于其他目的的数据行。现在,我想计算返回了多少行
    • 您是在另一个存储过程或 .net 中使用它吗?使用 .net,您可以获得返回的最后一个数据集。如果您在另一个存储过程中使用,您可能需要重组
    • 我现在明白了,我不会在另一个存储过程中使用它。我之前通过将它存储到临时表中来使用它(来自原始问题),但现在我只想选择行数。是否有一种简单的方法来使用数据集,使其不会显示在返回的列表中,以便我只获取计数值?
    猜你喜欢
    • 2021-10-04
    • 2014-04-21
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多