Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MS Access前端与SQL Server后端查询存储最佳实践_Sql Server_Ms Access_View_Parameters_Common Table Expression - Fatal编程技术网

Sql server MS Access前端与SQL Server后端查询存储最佳实践

Sql server MS Access前端与SQL Server后端查询存储最佳实践,sql-server,ms-access,view,parameters,common-table-expression,Sql Server,Ms Access,View,Parameters,Common Table Expression,我正在尝试更好地优化我的项目组织。使用MS Access作为前端,SQL Server作为后端,我的目标是尽可能多地分离,遵循最佳实践,并能够使用不同/多个前端(web、c#、python)。为了实现我的目标,我决定遵循一些设计决策: 尽可能使用视图在后端存储尽可能多的复杂查询 尽可能多地使用存储过程在后端进行处理 退出使用链接表,切换到使用简短查询在VBA代码中生成记录集 在玩SQL Server的一些流行功能时,我发现了自己无法解决的问题 CTE可以参数化。视图不能。那么存储在视图中的

我正在尝试更好地优化我的项目组织。使用MS Access作为前端,SQL Server作为后端,我的目标是尽可能多地分离,遵循最佳实践,并能够使用不同/多个前端(web、c#、python)。为了实现我的目标,我决定遵循一些设计决策:

  • 尽可能使用视图在后端存储尽可能多的复杂查询
  • 尽可能多地使用存储过程在后端进行处理
  • 退出使用链接表,切换到使用简短查询在VBA代码中生成记录集
在玩SQL Server的一些流行功能时,我发现了自己无法解决的问题

  • CTE可以参数化。视图不能。那么存储在视图中的CTE呢?如果答案是否定的,那么是否有其他方便的方法来存储CTE服务器端并从VBA调用它来构建记录集?其他参数化查询呢
  • 在MS Access中编写复杂的查询作为VBA代码是一件痛苦的事情。。。手指和眼睛。也许还有其他方法可以像老板一样在Access中存储查询
  • 你如何组织你的前端-后端应用程序,尤其是如果frontnend是MS Access,并且打算移动到任何其他平台
泰亚
烟雾。

CTE与是否有参数无关。CTE与在查询(或者现在是视图上的视图)上编写查询的想法完全相同。不必编写(并保存)两个视图?你可以使用CTE

然而,CTE在哪里最有用?尤其是在访问上下文中? Access SQL的一个非常好的特性是,别名列可以在该SQL的表达式中重复使用。使用T-SQL语法,您不能!。结果就是可怕的丑陋的T-SQL

以Access中的典型查询(Access SQL)尼斯(简单+简单)查询为例:

SELECT 
    ID, Company, State,
    (SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) as Purchased,
    (SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id) as Payments,
    (SELECT TaxRate from TaxRates where State = Customers.State) as TaxRate,
    (Purchased - Payments) as Balance,
    (Balance * TaxRate) as BalanceWithTax 
如你所见?在上面,我们使用一个子查询来获取购买、付款和税率。然后我们在表达式中使用这3个。 但是,对于T-SQL(SQL server),我们不能使用别名列。 那么,你现在明白了:

SELECT ID, Company, State,
(SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) as Purchased,
(SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id) as Payments,
(SELECT TaxRate from TaxRates where State = Customers.State) as TaxRate,
((SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) - 
(SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id)) as Balance,
( (SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) - 
(SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id)) * 
(SELECT TaxRate from TaxRates where State = Customers.State) as BAlanceWithTax
FROM Customers
以上是一个简单的例子。所以在上面的例子中,t-sql不允许在表达式中重复使用列(就像Access sql一样)。因此,上面提到的,或者说将Access SQL转换为T-SQL是一件非常痛苦的事情——完全痛苦

因此,我们可以在t-sql中使用CTE来“驯服”上述内容。我们可以去:

WITH MyCTE
AS
(SELECT ID, Company, State,
(SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) as Purchased,
(SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id) as Payments,
(SELECT TaxRate from TaxRates where State = Customers.State) as TaxRate
FROM Customers)

SELECT ID, Company, State, Purchases, Payments, TaxRate,
       (Purchases - Payments) as Balance,
       ( (Purchases - Payments) * TaxRate) as BalanceWithTax
         from mycte
现在,请注意我们仍然必须重复balance表达式,但至少现在我们可以在进一步的表达式中使用计算列,而不必重复它们。 因此,CTE是一个很好的特性,可以帮助您转换Access SQL中所有令人惊叹的查询,这些查询“非常好地”能够在T-SQL中重复(重用)任何经过序列化的表达式

至于热膨胀系数和参数?它们之间的连接为零。CTE不支持t-sql中的任何东西,也不比t-sql中的任何东西多或少有参数。(所以CTE和我在这里看到的参数之间没有联系)

但是,问题的答案是什么?你能在视野中使用CTE吗?是的,你可以,没有什么理由不这样做。在CTE之前,您可以使用一些技巧,或者(喘息)简单地创建一个视图,保存它,然后在该视图上创建另一个视图。因此,CTE实际上只是一种对查询执行查询的简单方法,无需创建单独的视图进行查询

但是,总而言之,CTE可以用作视图,主要原因是T-SQL缺少Access SQL的可爱功能,它允许在T-SQL没有的情况下重复使用别名列。因此,在尝试将Access SQL转换为T-SQL时,CTE的问题尤其重要—它使您重新获得Access在SQL中所具有的这一奇妙功能,以及T-SQL语法中您将严重错过的一项功能

在MS Access中编写复杂的查询作为VBA代码是一件痛苦的事情

嗯,我不能说.net或其他大多数语言中的代码中的内嵌sql也很干净。您倾向于使用字符串连接,这总是一个挑战,但我不能说在say.net开发中使用字符串连接比使用VBA要好得多。 然而,在大多数情况下

将sql文本作为保存的查询放在Access中,然后在代码中使用它。 那么,用我们上面的例子运行

您可以在代码中使用此选项:

dim strSQL    as string
strSQL = "SELECT ID, Company, State," & _
"(SELECT SUM(Price) FROM Purchases where Customer_ID = Customers.ID) as Purchased," & 
"(SELECT SUM(Payment) FROM Payments where Customer_ID = Customers.id) as Payments," & _
"(SELECT TaxRate from TaxRates where State = Customers.State) as TaxRate," & _
"(Purchased - Payments) as Balance," & _
"(Balance * TaxRate) as BalanceWithTax " & _

dim rst     as DAO.RecordSet
set rst = CurrentDB.OpenRecordSet(strSQL)
不能说上面的内容比用大多数其他语言写上面的内容更糟糕。 但是,当然可以(在Access VBA中,典型的做法是)保存该查询,因此上面的代码成为一行代码

例如:

因此,VBA中丑陋的内嵌式sql肯定可以通过保存这些查询而不是将它们写在代码中来“驯服”。如果您使用内嵌式sql,我不能说.net会更好(因为您必须处理连接对象、命令对象,而且在大多数情况下还必须处理数据适配器?那么,.net代码会变得更加冗长,需要比VBA中的一行代码更多的代码来完成同样的事情

好的,这就解决了CTE问题,以及在VBA代码中使用SQL的问题

至于在Access中组织FE?好吧,以最少的工作量获得最好的性能?毫无疑问,视图是一种方式。原因是Access非常好

如果您在Access中有一个表单,请说直接绑定到链接表。在sql server之前,该表单将绑定到accDB后端

假设有一百万行。 假设access后端是文件夹中的共享accDB。 假设表单基于此链接表

那么,在过去,您如何启动+加载并显示一条记录,而只从网络管道中拉出一条记录呢? 嗯,除非通过where子句,否则不会启动表单

您可以这样做:

dim strInvoice   as string
strInvoice = InputBox("Enter invoice number")
docmd.OpenForm "frmInvoices",,,"InvoiceNum = " & strInvoice
好吧,现在Access只会从网络管道中拖出一条记录,而不是整个表

现在,假设我们将BE表迁移到SQL server? 现在,假设我们仍然将发票表单链接到该链接
dim strInvoice   as string
strInvoice = InputBox("Enter invoice number")
docmd.OpenForm "frmInvoices",,,"InvoiceNum = " & strInvoice
dim strInvoice   as string
strInvoice = InputBox("Enter invoice number")
docmd.OpenForm "frmInvoices",,,"InvoiceNum = " & strInvoice
with CurrentDB.queryDefs("ptGetIvnoice")
   .SQL = "Exec GetInoice " & strInvoice
   rst = .OpenRecordSet
end with