如何在视图中调用存储过程?

42

我该如何在一个视图中调用返回数据的存储过程?这是否可行?


重复:https://dev59.com/znRC5IYBdhLWcg3wSu57 - Russ
7个回答

28

在 SQL Server 中,这种构造方式是不允许的。内联表值函数可以作为参数化视图执行,但仍然不允许像这样调用存储过程。

下面是一些使用存储过程和内联表值函数可互换的示例 - 你会发现内联表值函数更加灵活(它基本上更像一个视图而不是函数),所以当可以使用内联表值函数时,它们可以更具重复使用性:

CREATE TABLE dbo.so916784 (
    num int
)
GO

INSERT INTO dbo.so916784 VALUES (0)
INSERT INTO dbo.so916784 VALUES (1)
INSERT INTO dbo.so916784 VALUES (2)
INSERT INTO dbo.so916784 VALUES (3)
INSERT INTO dbo.so916784 VALUES (4)
INSERT INTO dbo.so916784 VALUES (5)
INSERT INTO dbo.so916784 VALUES (6)
INSERT INTO dbo.so916784 VALUES (7)
INSERT INTO dbo.so916784 VALUES (8)
INSERT INTO dbo.so916784 VALUES (9)
GO

CREATE PROCEDURE dbo.usp_so916784 @mod AS int
AS 
BEGIN
    SELECT  *
    FROM    dbo.so916784
    WHERE   num % @mod = 0
END
GO

CREATE FUNCTION dbo.tvf_so916784 (@mod AS int)
RETURNS TABLE
    AS
RETURN
    (
     SELECT *
     FROM   dbo.so916784
     WHERE  num % @mod = 0
    )
GO    

EXEC dbo.usp_so916784 3
EXEC dbo.usp_so916784 4

SELECT * FROM dbo.tvf_so916784(3)    
SELECT * FROM dbo.tvf_so916784(4)

DROP FUNCTION dbo.tvf_so916784
DROP PROCEDURE dbo.usp_so916784
DROP TABLE dbo.so916784

这些表值函数在Oracle数据库中也被支持吗? - Krutik

17
exec sp_addlinkedserver 
        @server = 'local',
        @srvproduct = '',
        @provider='SQLNCLI',
        @datasrc = @@SERVERNAME
go

create view ViewTest
as
select * from openquery(local, 'sp_who')
go

select * from ViewTest
go

我尝试了这个,但当我尝试运行select * from openquery时,它告诉我:OLE DB提供程序“SQLNCLI11”返回消息“登录超时”。 - Matthew Goodwin

6

我能够在视图中调用存储过程(SQL Server 2005)。

CREATE FUNCTION [dbo].[dimMeasure] 
   RETURNS  TABLE  AS

    (
     SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost; Trusted_Connection=yes;', 'exec ceaw.dbo.sp_dimMeasure2')
    )
RETURN
GO

在存储过程中,我们需要设置:

set nocount on
SET FMTONLY OFF

CREATE VIEW [dbo].[dimMeasure]
AS

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 'exec ceaw.dbo.sp_dimMeasure2')

GO

3
如果您正在使用SQL Server 2005,则可以使用表值函数。 您可以直接调用它们并传递参数,同时将它们视为表格。
有关更多信息,请查看Table-Valued User-Defined Functions

似乎在SQL Server 2000中也可以使用表值函数:http://www.devarticles.com/c/a/SQL-Server/Creating-User-Defined-Functions-In-SQL-Server-2000/4/ - polara

0
create view sampleView as 
select field1, field2, ... 
from dbo.MyTableValueFunction

请注意,即使您的MyTableValueFunction不接受任何参数,您仍然需要在其后面包括括号,例如:
... from dbo.MyTableValueFunction()

如果没有括号,你会得到一个“无效的对象名称”错误。


0

您需要像下面这样编写视图脚本。 您基本上需要将存储过程的结果写入表变量或临时表,然后选择到视图中。

编辑 - 如果您可以将存储过程更改为表值函数,则可以消除选择到临时表的步骤。

**编辑2 ** - 评论正确,不能像我建议的那样将sproc读入视图。相反,将您的存储过程转换为表值函数,如其他帖子中所述,并从中进行选择:

create view sampleView
as select field1, field2, ... 
from dbo.MyTableValueFunction

对于造成的困惑,我深表歉意。


我非常确定在SQL Server中无法做到这一点。 - Cade Roux
实际上,我确定你做不到这一点,因为视图本来就不允许有BEGIN END块。 - Cade Roux
你是正确的...正在调查中。我知道以类似的方式填充视图。 - Rob Allen
我不想暗示你不能在另一个步骤中填充表格并从该表格创建视图。但是没有任何触发器可以自动触发该填充过程。还有OPENROWSET技巧,但它也有其他缺点。 - Cade Roux
@Cade Roux - 实际上,openrowset 是一个 hackish 解决方案。你可以填充一个 #temp 表,在同一个连接中使用它来消耗视图 - 但这只是在寻求麻烦。 - Rob Allen

0

我所找到的最简单的解决方案就是从存储过程返回的数据中创建一张表,然后再从该表创建一个视图:

在从存储过程选择数据的最后一步插入以下代码: SELECT * into table1 FROM #Temp

创建视图 vw_view1,并从 table1 中选择所有内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接