SQL View与Microsoft Access查询

时间:2016-07-30 13:01:31

标签: sql ms-access view

虽然大多数SQL数据库允许您创建视图,但Microsoft Access已保存查询。我已经读过Access Queries与SQL视图不同,但这是一个彻底的陈述。

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

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

由于

2 个答案:

答案 0 :(得分:2)

非常广泛地说,观点提供:

  • 性能

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

    • 允许您显示数据子集,而不授予对构成视图的基本视图或表的访问权。
  • 更轻松的部署
    • 使用Access,您对已保存的查询进行了更改,您很可能必须将Access数据库部署到所有用户。使用“视图”,您可以进行更改,并且会影响所有用户。

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

  

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

这不完全正确。通常首选在视图中按名称标识列,因为它们代表数据的子集,并且它限制最终用户看到的数据。也就是说,通常情况下,任何SQL查询显然都可以限制所包含的列,无论它是否为Access Query。但是你仍会遇到SELECT *的观点,所以它本身并没有区别。

答案 1 :(得分:2)

Access"已保存的查询"不仅仅是SQL Server中的一个视图(其中"更多"并不意味着它更好或不更好)。在SQL Server中,您具有SQL文本和定义视图的执行计划。您还可以使用对视图本身没有影响的用户定义值添加描述文本或用户定义变量等其他信息。

在Access中,您使用的是QueryDef对象,实际上是"保存的查询",它们不仅包含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(物料清单)这样的层次结构,您可以使用它。使用Access SQL作为T-SQL可以使用递归SQL。在Access中,它只能通过在Access SQL中使用VBA函数来减慢整个查询的速度。

当然Access中的QueryDef对象也可以使用所谓的" Pass-Through-Queries"在不使用Access SQL的情况下直接执行即T-SQL。但是当SQL文本在本地保存在Access中时,它在SQL Server中作为动态SQL处理,因为每次执行时都会发送文本,并且SQL Server没有保存的视图,因此保存的视图的所有优点都将丢失。最好避免使用它们或仅将它们用于在SQL Server上执行保存的视图,函数或存储过程。

QueryDef对象还是一个DAO对象,这意味着您始终使用DAO数据类型。因此,即使是Pass-Through-Query,数据也始终从SQL Server(当然还有其他数据库)数据类型转换为DAO数据类型。

如上所述更容易部署:如果将两者用于前端目的(如表单的RecordSource属性),则在Access中使用视图或QueryDef没有太大区别。原因是QueryDef和视图都需要在前端实现,QueryDef需要在本地更改,视图可以在后端更改,但因为它在大多数情况下作为链接表链接到前端您需要删除前端中的此链接并在视图更改时重新创建它,因此您还需要重新部署前端(这就是为什么我个人更喜欢ADP而不是ACCDB,因为在ADP中我直接在Access中工作使用视图而不是任何QueryDef所以这里后端的更改足以在前端反映它。 如果您在前端使用的视图中更改了字段名,则还需要重新部署前端。

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

SELECT * "拼出字段列表"确实是SQL Server视图的作用,问题是:它保存了在保存视图时在SELECT中使用的表对象的字段列表。但它并没有明显地保存这个字段列表。如果打开视图的SQL文本,您将始终只看到" *",而不是视图已保存的字段列表。这是SQL Server中的一个大问题,因为您可以预期它会列出该表始终具有的所有字段(这是Access在具有SELECT *的QueryDef对象中执行的操作)。因此,即使您使用像RedGate的免费SQL搜索这样的工具,您也不会找到该视图,因为您没有SQL文本中的字段列表,因此无法找到更改的表字段的字段名称。

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

如果在SQL Server中使用CTE,则最后一个SELECT选择CTE中先前SELECT的所有字段。这里使用星号没有问题,因为字段名称(应该)列在同一查询的先前SELECT中。但总的来说,更常见的是避免将其用作生产目的。

这些只是两者之间差异的例子,还有更多如上所述(索引视图,安全模型)或类似模式名称的内容,但这应该会给你一张图片。