如何解决Access 或 SQL:需要帮助从字段名称在查询中动态选择的字段返回数据
我在 sql 中设置了一个旧数据库,就像一个有 50 列的电子表格。除员工姓名外,字段名称将是 Machine01、Machine02 等,并且记录将包括在每台机器上认证的日期。我将 Access 用作传统前端,因为已经有很多人使用它进行编码和培训。
我将如何编写一个查询来提供每个人的认证日期,例如 Machine27? 在 Access 中,我最初拥有
SELECT LastName,FirstName,Forms![F: Reports Switchboard]![Machine Name] As Expr1
FROM Certifications
WHERE Forms![F: Reports Switchboard]![Machine Name]>""
但这提供了一个填充机器名称的列,而不是具有该名称的字段中的日期。
CREATE PROCEDURE sp_CertDate
@fieldvar1 varchar(20)
AS
SELECT LastName,@fieldvar1
FROM Certifications
WHERE Forms![F: Reports Switchboard]![Machine Name]>""
GO
我想我遗漏了一些明显的东西,但我需要朝着正确的方向努力。任何帮助将不胜感激。
解决方法
由于机器名称是一列表,它是 SQL 语句的结构组件,而不是字符串文字。因此,您需要创建一个动态查询对象,您可以使用 QueryDefs 在 VBA 中处理该对象:
Dim qDef As QueryDef
Dim strSQL As String
strSQL = "SELECT LastName,FirstName," _
& "[" & Forms![F: Reports Switchboard]![Machine Name] & "] As MachineDate " _
& "FROM Certifications " _
& "WHERE [" & Forms![F: Reports Switchboard]![Machine Name] & "] >'' "
Set qdef = CurrentDb.QueryDefs("mySavedQuery") ' LOCATE SAVED QUERY
qdef.SQL = strSQL ' CHANGE ITS SQL
Set qdef = Nothing ' RELEASE OBJECT TO SAVE
但理想情况下,如果您可以避免使用宽格式数据,因为您永远不想在列标题中保存数据元素。正如一位 DBA 大师所说,Why would you need to create a table with even 20 columns,let alone 2000 ???。
改为使用更规范化的长表格式并避免复杂查询:
姓氏 | 名字 | 机器 | 日期 |
---|---|---|---|
堆栈 | 瑞克 | Machine01 | 5/1/21 |
堆栈 | 瑞克 | Machine02 | 5/15/21 |
堆栈 | 瑞克 | Machine03 | 5/20/21 |
... | ... | ... | ... |
这样做,不需要 VBA,只需要一个静态 SQL 查询:
SELECT LastName,Machine,[Date]
FROM Certifications
WHERE Machine = Forms![F: Reports Switchboard]![Machine Name]
,
表和字段名称在 Access 查询对象中不能是动态的。
我假设有一个像 EmpID 这样的唯一标识符字段。如果没有,应该有。
可能的选择:
-
每个机器字段都具有与 OR 运算符相同的条件 - 50 个字段可能会达到 OR 运算符数量的限制,显然 AND 运算符的数量限制为 99 个
-
构建一个 UNION 查询以将机器字段重新排列为规范化结构,并使用该查询作为另一个查询的源进行搜索 - UNION 限制为 50 条 SELECT 行,因此可能几乎无法工作,并且没有构建器或向导对于 UNION,必须在 SQLView 中键入或复制/粘贴
SELECT EmpID,LastName,Machine01 AS CertDate,"Machine01" AS MachineName FROM Certifications
UNION SELECT EmpID,Machine02,"Machine02" FROM Certifications
...;
- 在指定机器字段上使用DLookup域聚合函数,字段参数输入参考表单控制
SELECT EmpID,Forms![F: Reports Switchboard]![Machine Name] AS MachineName,DLookup("[" & Forms![F: Reports Switchboard]![Machine Name] & "]","Certifications","EmpID=" & [EmpID]) AS CertDate
FROM Certifications;
- VBA 和 QueryDefs 来修改查询对象
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。