繁体   English   中英

SQL View与Microsoft Access查询

[英]SQL View vs Microsoft Access Query

虽然大多数SQL数据库允许您创建视图,但是Microsoft Access已保存查询。 我已经读过,访问查询与SQL视图不是一回事,但这是一条笼统的声明。

我知道他们在细节上有些差异。 例如,Access将按原样保存SELECT * ,而大多数保存的视图将列出字段列表。

除了这些细节之外,两者之间是否还有根本区别?

谢谢

从广义上讲,“意见”提供:

  • 性能

    • 受益于执行计划,对于非索引视图,执行计划将使用视图和构成视图定义的查询来分析查询。 然后存储这些计划,以便重复和/或类似的查询可以更快地检索数据。 供参考: 查看分辨率
    • 诸如以下情况的索引视图:基础表不是非常重要的事务(OLTP)并且数据集很大并且需要聚合时(例如在OLAP源中)。 供参考: 使用SQL Server 2008索引视图提高性能
  • 安全

    • 允许您呈现数据的子集,而无需授予对构成该视图的基本视图或表的访问权限。
  • 易于部署
    • 使用Access,您可以对保存的查询进行更改,您很有可能必须将该Access数据库推出给所有用户。 使用视图,您进行更改,这将影响所有用户。

关于最后一点,假设您没有更改视图中其他地方引用的标识符。 一个简单的示例是在视图中更改列名称。 这很可能需要更改其他从属数据库对象或访问它的外部工具中的名称。

我知道他们在细节上有些差异。 例如,Access将按原样保存SELECT *,而大多数保存的视图将列出字段列表。

严格来说不是这样。 通常,最好在视图中按名称标识列,因为它们代表数据的子集 ,并且限制了最终用户可以看到哪些数据。 就是说,一般而言,无论是否为访问查询,您都可以明显地限制所有包含的列的SQL查询。 但是您仍然会遇到带有SELECT * Views,因此它本身没有区别。

Access“已保存的查询”不只是SQL Server中的视图(“更多”并不意味着它更好还是不更好)。 在SQL Server中,您具有SQL文本和定义视图的执行计划。 您还可以添加其他信息,例如描述文本或具有用户定义值的用户定义变量,这些信息不会影响视图本身。

在Access中,您使用的是QueryDef对象,它们实际上是“已保存的查询”,它们包含的内容远远超过SQL文本,而SQL文本只是QueryDef对象的一个​​属性。 例如,您可以使用PARAMETERS子句定义参数,该子句可以与SQL Server存储过程/函数中的@ -variables相似地使用。 这对于SQL Server视图是不存在的。 当然,QueryDef对象也具有保存的执行计划,这就是为什么Microsoft还建议在同一位置使用QueryDef作为RecordSource而不是动态SQL命令的原因。 通过一些注册表技巧,JET / ACE查询优化器的结果也可以显示出来,它不仅不是Access GUI的一部分,所以大多数人不知道它也有执行计划。 QueryDef对象还包含格式设置属性,在数据表视图中显示的标题,组合框的查找定义,ODBC连接字符串等等,您可以在Access帮助中找到它们。

因此,Access QueryDefs包含很多内容,仅影响结果的显示,这对于使用Access可以开发的前端是有意义的,但是与SQL Server视图相比,它们没有太多优势。 一个简单的区别是SQL语言:与您使用的后端无关,您正在使用Access SQL,并且此SQL实际上是非常基本的SQL。 例如,SQL Server上的T-SQL是一种非常强大的SQL语言,您可以在其中做更多的事情-例如,您可以使用一个SQL语句来查询诸如BOM(物料清单)之类的层次结构。访问SQL就像T-SQL可以使用递归SQL。 在Access中,只能使用Access SQL中的VBA函数,这会大大降低完整查询的速度。

当然,Access中的QueryDef对象也可以使用所谓的“传递查询”,它直接执行T-SQL,而无需使用Access SQL。 但是由于SQL文本在Access中本地保存,因此在SQL Server中将其作为动态SQL处理,因为每次执行该文本时都会发送该文本,并且SQL Server没有为此保存的视图,因此失去了保存视图的所有优点。 最好避免使用它们,或仅将它们用于在SQL Server上执行保存的视图,函数或存储过程。

而且,QueryDef对象是DAO对象,这意味着您始终在使用DAO数据类型。 因此,即使在通过查询的情况下,数据也始终会从SQL Server(当然还有其他数据库)数据类型转换为DAO数据类型。

像上面提到的那样更容易部署:如果将视图或QueryDef都用于前端目的(例如表单的RecordSource属性),则在Access中使用视图或QueryDef并没有太大区别。 原因是QueryDef和视图都需要在前端中实现,QueryDef需要在本地进行更改,视图可以在后端中进行更改,但是因为在大多数情况下它是作为链接表链接到前端的您需要在前端中删除此链接并在视图发生更改的情况下重新创建它,因此还需要重新部署前端(这就是我个人更喜欢ADP而不是ACCDB的原因,因为在ADP中,我直接在Access中使用视图和不使用任何QueryDef,因此此处的后端更改足以将其反映在前端中)。 与此无关,如果在前端中使用的视图中更改字段名称,则还需要重新部署前端。

如果仅在后端使用视图来为其他后端目的组装数据(例如在存储过程或其他视图中使用),则是另一回事。 如果它们未链接到前端,则无需重新部署前端。 因此,对于存储过程和函数,对于视图来说也是如此,如果您需要修复不会直接影响前端的内容,则可以在后端快速更改某些内容。 即,如果将两个文本字段连接为“。”。 使用别名,有人告诉您现在它必须是“-”,而您只需更改视图即可完成,前端无任何更改(如果前端没有进一步的逻辑需要检查点)。

SELECT *“拼出字段列表”确实是SQL Server视图所执行的操作,问题是:它保存了在保存视图时在SELECT中使用的表对象的字段列表。 但是,它不会明显地保存此字段列表。 如果打开视图的SQL文本,则始终只会看到“ *”,而不会看到视图已保存的字段列表。 这是SQL Server中的一个大问题,因为您希望它始终列出表具有的所有字段(这就是Access在使用SELECT *的QueryDef对象中所做的事情)。 因此,即使您使用RedGate的免费SQL Search之类的工具,也不会找到该视图,因为您在SQL文本中没有字段列表,因此无法找到已更改表字段的字段名称。

通常,尽可能避免使用“ SELECT *”,因为它产生的问题多于它没有任何优势。 结果始终使用您真正想要的字段列表。 在Access中,如果您更改表中的字段名(如果在Access选项中启用了AutoRename),则这些字段名将自动更改,在SQL Server中,您可以使用特定字段搜索所有对象并进行更改。

一个例外是,如果您在SQL Server中使用CTE,则最后一个SELECT选择CTE中先前SELECT的所有字段。 在这里使用星号没有问题,因为(应该)在同一查询的先前SELECT中列出了字段名称。 但总的来说,最好避免使用它作为生产用途。

这些只是两者之间差异的示例,还有很多类似上面提到的内容(索引视图,安全模型)或诸如模式名称之类的东西,但这应该可以给您带来一幅图画。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM