【问题标题】:What is the difference between a stored procedure and a view?存储过程和视图有什么区别?
【发布时间】:2011-07-08 21:01:22
【问题描述】:

我对几点感到困惑:

  1. 存储过程和视图有什么区别?

  2. 在 SQL Server 中什么时候应该使用存储过程,什么时候应该使用视图?

  3. 视图是否允许创建可以传递参数的动态查询?

  4. 哪一个是最快的,一个比另一个快的依据是什么?

  5. 视图或存储过程是否永久分配内存?

  6. 如果有人说视图创建一个虚拟表,而过程创建一个材料表,这是什么意思?

如果有更多积分,请告诉我。

【问题讨论】:

  • 我想问什么时候应该使用视图而不是存储过程。

标签: sql sql-server-2005 stored-procedures views


【解决方案1】:

一个视图代表一个虚拟表。您可以在一个视图中连接多个表,并使用该视图来呈现数据,就好像数据来自单个表一样。

存储过程使用参数来执行功能......无论是更新和插入数据,还是返回单个值或数据集。

Creating Views and Stored Procedures - 从 Microsoft 获得一些关于何时以及为何使用它们的信息。

假设我有两张桌子:

  • tbl_user,带列:user_iduser_nameuser_pw
  • tbl_profile,带列:profile_iduser_idprofile_description

所以,如果我发现自己从这些表中查询了很多...而不是在每条 SQL 中进行连接,我会定义如下视图:

CREATE VIEW vw_user_profile
AS
  SELECT A.user_id, B.profile_description
  FROM tbl_user A LEFT JOIN tbl_profile B ON A.user_id = b.user_id
GO

因此,如果我以后想通过user_id查询profile_description,我所要做的就是:

SELECT profile_description FROM vw_user_profile WHERE user_id = @ID

该代码可用于以下存储过程:

CREATE PROCEDURE dbo.getDesc
    @ID int
AS
BEGIN
    SELECT profile_description FROM vw_user_profile WHERE user_id = @ID
END
GO

所以,稍后,我可以打电话:

dbo.getDesc 25

我会得到user_id 25 的描述,其中25 是你的参数。

显然还有很多细节,这只是基本的想法。

【讨论】:

  • 但是我可以加入可以加入存储过程中的多个表以及我不必提供参数的地方。
  • 但你为什么要这样做?你想达到什么目的?您可以将视图用作表格...存储过程用于做事...视图使您的生活更轻松。
  • 将视图视为存储的查询,因此如果您有两个表,您发现您必须加入很多表才能完成工作,您可以创建一个视图来处理,这样您就没有一直加入他们。
  • 我没有得到,请多描述一下。
  • 是的,但它会存储您的视图...这样您就可以将其称为单个表。这样你就创建了一次连接,以后的任何使用都会直接引用视图,该视图调用底层 sql,就好像它是一个表一样。
【解决方案2】:

大量可用信息here

这是一个很好的总结:

一个存储过程:

  • 接受参数
  • 可以在更大的查询中用作构建块
  • 可以包含多个语句、循环、IF ELSE 等。
  • 可以对一个或多个表进行修改
  • 不能用作 INSERT、UPDATE 或 DELETE 的目标 陈述。

观点:

  • 是否接受参数
  • 可以在更大的查询中用作构建块
  • 只能包含一个 SELECT 查询
  • 可以对任何表进行修改
  • 但可以(有时)用作 INSERT、UPDATE 或 删除语句。

【讨论】:

  • 另外,视图不应包含任何“order by”或“top”子句
  • “不能用作 INSERT、UPDATE 或 DELETE 语句的目标”是什么意思?我们不能在存储过程中使用 INSERT、DELETE、UPDATE 吗?
  • “一个视图,不接受参数”,这不是真的吗?视频例如:youtube.com/watch?v=zK-mWjUxKpw
  • 视图可以对基表/表进行修改:csharp-video-tutorials.blogspot.com/2012/09/…
  • @ArsmanAhmad 澄清一下:您可以在存储过程中使用 INSERT、UPDATE 和 DELETE。但存储过程不能是 INSERT、UPDATE 或 DELETE 语句的目标。例如:您不能将数据插入存储过程。存储过程不是任何类型的表,因此您不能向其中插入数据、更新其中的数据或删除其中的数据。
【解决方案3】:

首先你需要明白,两者是不同的东西。 Stored Procedures 最适合用于 INSERT-UPDATE-DELETE 语句。而Views 用于SELECT 语句。您应该同时使用它们。

在视图中你不能改变数据。一些数据库有可更新的视图,你可以在Views上使用INSERT-UPDATE-DELETE

【讨论】:

  • 您可以使用视图更改基础表中的数据。视图是可更新的。
  • 视图是可更新的,但有一定的条件:您可以在视图的 from 子句中的一个基表中更新/插入数据。
【解决方案4】:

SQL 视图是一个基于 SQL SELECT 查询的虚拟表。视图引用一个或多个现有数据库表或其他视图。它是数据库的快照,而存储过程是编译成单个执行计划的一组 Transact-SQL 语句。

视图只是展示存储在数据库表中的数据,而存储过程是一组可以执行的语句。

视图更快,因为它显示引用的表中的数据,而存储过程执行 sql 语句。

查看这篇文章:View vs Stored Procedures。正是你要找的东西

【讨论】:

    【解决方案5】:

    除了上面的cmets,我想补充几点关于Views。

    1. 视图可用于隐藏复杂性。想象一个场景,有 5 个人在做一个项目,但其中只有一个人对复杂联接之类的数据库非常擅长。在这种情况下,他可以创建视图,以便其他团队成员在查询任何单个表时轻松查询。
    2. Views 可以轻松实现安全性。假设我们的表 Employee 包含敏感列,如 SalarySSN 号码。这些列不应该对无权查看它们的用户可见。在这种情况下,我们可以创建一个视图来选择表中不需要任何授权(如 NameAge 等)的列,而不会暴露敏感列(如 Salary 等. 我们之前提到过)。现在我们可以删除直接查询表Employee的权限,只保留视图的读取权限。这样,我们就可以使用 Views 来实现安全性。

    【讨论】:

      【解决方案6】:
      1. VIEW 是一种动态查询,您可以在其中使用“WHERE”子句
      2. 存储过程是一个固定的数据选择,它返回一个预定义的结果
      3. 视图和存储过程都不会分配内存。只有物化视图
      4. 一个 TABLE 只是一个 ENTITY,一个视图可以从不同的 ENTITIES 或 TABLES 中收集数据

      【讨论】:

        【解决方案7】:

        视图是一种在数据库中保存复杂SELECT 的简单方法。

        当简单的 SQL 不够用时,使用存储过程。存储过程包含变量、循环和对其他存储过程的调用。它是一种编程语言,而不是查询语言。

        1. 视图是静态的。将它们视为具有特定布局的新表,其中的数据是使用您创建它的查询动态创建的。与任何 SQL 表一样,您可以使用 WHEREGROUP BYORDER BY 对其进行排序和过滤。

        2. 这取决于你做什么。

        3. 取决于数据库。简单视图只需运行查询并过滤结果。但是像 Oracle 这样的数据库允许创建一个“物化”视图,它基本上是一个表,当视图的基础数据发生变化时会自动更新。

          物化视图允许您在视图的列上创建索引(尤其是在数据库中不存在的计算列上)。

        4. 我不明白你在说什么。

        【讨论】:

          【解决方案8】:

          当 Mahesh 建议您不能更改视图中的数据时,他并不完全正确。所以在帕特里克看来

          CREATE View vw_user_profile AS 
          Select A.user_id, B.profile_description
          FROM tbl_user A left join tbl_profile B on A.user_id = b.user_id
          

          我可以更新数据...例如,我可以执行其中任何一项...

          Update vw_user_profile Set profile_description='Manager' where user_id=4
          

          Update tbl_profile Set profile_description='Manager' where user_id=4
          

          您不能插入到该视图,因为并非所有表中的所有字段都存在,并且我假设 PROFILE_ID 是主键并且不能为 NULL。 但是,您有时可以插入到视图中...

          我使用 ... 在现有表上创建了一个视图

          Create View Junk as SELECT * from [TableName]
          

          那么

          Insert into junk (Code,name) values 
          ('glyn','Glyn Roberts'),
          ('Mary','Maryann Roberts')
          

          DELETE from Junk Where ID>4
          

          INSERT 和 DELETE 在这种情况下都有效

          显然,您无法更新任何聚合或计算的字段,但任何只是直接视图的视图都应该是可更新的。

          如果视图包含多个表,则不能插入或删除,但如果视图只是一个表的子集,则通常可以。

          【讨论】:

            【解决方案9】:

            主要区别在于,当您查询视图时,会将其定义粘贴到您的查询中。程序也可以给出查询结果,但它是编译的,所以速度更快。另一种选择是索引视图..

            【讨论】:

              【解决方案10】:

              @Patrick 的说法是正确的,但要回答您的其他问题,视图将在内存中创建自己,并且取决于连接、数据的类型以及是否进行了任何聚合,这可能会占用大量内存查看。

              存储过程使用临时哈希表(例如#tmpTable1)或使用@tmpTable1 在内存中进行所有处理。取决于你想让它做什么。

              存储过程类似于函数,但直接通过其名称调用。而不是在查询本身中实际使用的函数。

              如果您不检索大量数据,显然大多数时候内存表会更快。

              【讨论】:

                猜你喜欢
                • 2015-10-28
                • 1970-01-01
                • 1970-01-01
                • 2015-09-25
                • 2011-02-10
                • 2010-09-18
                • 2018-06-21
                • 2022-06-15
                • 1970-01-01
                相关资源
                最近更新 更多