单元格内容作为 Excel 中“WHERE”语句的一部分
Posted
技术标签:
【中文标题】单元格内容作为 Excel 中“WHERE”语句的一部分【英文标题】:Cell Contents as Part of a 'WHERE' Statement in Excel 【发布时间】:2017-08-28 17:05:08 【问题描述】:我已经搜索了几个星期,但在找到以下问题的答案方面没有取得太大成功......
我能否在 Excel 中(在开发人员选项中)创建一个文本框,然后让用户输入的文本框内容成为 SQL (T-SQL) 中 WHERE 语句的一部分?理想情况下,我希望用户能够输入一个 3 位数的 ID 号码,然后点击搜索按钮以在相同或不同的工作表上显示结果列表。如果文本框不简单,那么我将满足于引用单元格的内容来代替文本框的内容。
类似这样的:
SELECT T.CustomerName, T.NetAmount, T.TransactionType
FROM TheDatabase.dbo.TransactionsTable T
WHERE T.ScheduledDate > '2016-01-01' AND
(T.Status = 'InProcess' OR T.Status = 'Completed') AND
T.CustomerID = [textbox1.contents / cell(A1).. something]
我知道 SQL 不是为这样工作而设计的,但我希望它能说明我想要完成的工作。
一些背景:
我将一些职责转交给一位同事,因为我要换一个角色。我有一个定期运行的报告,它为我提供有关应付账款交易的统计信息。我必须在一夜之间学习一些基本的 SQL,并且在设计 SELECT 语句和边学习边学习方面非常成功。问题是,每当我需要将新客户(基本上是一个 3 位数字)添加到我的帐户列表中以进行审查时,我都必须修改查询。这对我来说没什么大不了的,我只是打开 PowerQuery,选择高级视图,然后编辑代码。我不能为下一个人修复工具,所以我需要一种方法,他们可以搜索他们想要的客户。
我可以加载所有客户,但主表中有超过 360 万笔交易,我们查看了 30 多个字段。另外,我将 3 个数据库中的至少 6 个表连接在一起以提取和计算所有信息。上次我尝试检索所有交易数据时,由于系统内存不足,我无法生产。我唯一一次成功查询到这么多数据花了将近 10 分钟。老实说,这对我来说不是问题,但是这个人必须一直运行它,我需要加快速度。如我所见,消除问题的唯一方法是只提取我需要的交易。当我现在这样做时,大约需要 3 秒。
我一直在使用的查询是在 Microsoft SQL Server Management Studio 中创建的,我基本上是在 Excel 中创建查询时复制查询并将其粘贴到“高级”框中。
任何关于这方面的建议都会对现在和未来的项目有所帮助!
【问题讨论】:
首先,您正在寻找IN
子句WHERE T.CustomerID IN (list of comma separated int values, or one column query resulset)
第二,不知道你是如何设法执行 SQL 语句的。是在 Excel 里面吗?
第三,它看起来像一个XY问题,试着描述你的实际需要而不是你的解决方法。 meta.stackexchange.com/questions/66377/what-is-the-xy-problem
【参考方案1】:
在 Excel VBA 中,您可以打开与数据库的 SQL 连接。但是您需要正确的权限和密码才能执行此操作。也许贵公司的技术人员可以提供帮助。
然后您需要构建您的 SQL 代码并发送它。然后检索结果。您可以通过多种方式显示结果。
这里有一些代码可以帮助您入门:
Set objMyConn = New ADODB.Connection
Set objMyRecordset = New ADODB.Recordset
Dim strSQLText As String ' Declare a string to build your SQL in
'Open your connection
objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=TheDatabase;User ID=xyz;Password=xyz;"
objMyConn.Open
strSQLText = "SELECT T.CustomerName, T.NetAmount, T.TransactionType " & _
"FROM TheDatabase.dbo.TransactionsTable T " & _
"WHERE T.ScheduledDate > '2016-01-01' AND " & _
"(T.Status = 'InProcess' OR T.Status = 'Completed') AND " & _
"T.CustomerID = '" & _
Me.textbox1.Value & "';"
Set objMyRecordset.ActiveConnection = objMyConn
objMyRecordset.Open strSQLText
ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)
此代码假定您的 T.CustomerID 是 varchar。如果它是整数(或其他数据类型),则需要从 SQLText 中删除 textbox1.Value
周围的单引号
您可能还希望将结果保存在单元格“A1”以外的位置。显示结果的方式/位置很多。
此外,此代码假定 textbox1.Value
中只有一个 ID。首先让这个 SQL 只使用 1 个客户代码。如果您需要返回多个客户的数据,您可以稍后再做这件事,只需稍加努力即可。
希望你能开始。
【讨论】:
另请注意,此代码易受 SQL 注入攻击。我相当肯定,如果我输入'; drop table TheDatabase.dbo.TransactionsTable;--
,您的整个 TransactionsTable 都会消失。
@Nzall:非常正确。每当您想构建快速的初学者级别的 SQL 以允许用户输入拼接到代码中的数据时,您都会将其开放给不良玩家造成破坏。为了缓解这个问题,您需要学习将变量作为参数传递的编码技术。希望他公司的初学者不要破坏他们的数据。但如果这是一个真正的问题,他们应该让公司的数据库程序员为他们编写代码。真正担心的 DBA 不会一开始就给他们连接字符串信息。指出 Nzall 是件好事。
@abraxascarab 恕我直言,最好在一开始就学习正确的习惯(参数化查询),而不是学习通过字符串连接进行查询,然后再取消学习。
@alroc:非常正确。然而,OP 声明他正在换工作,目前还不清楚他是否会成为一名程序员。理想情况下,公司应该有一个程序员为他做这个查询。再加上他的解释有点模糊。而且由于没有其他人在帮助他,我的回答将他引向了一个可行的简单答案。我实际上是希望有人能更无私地利用他们的时间,并为他写一个关于参数化查询的初学者解释。提示提示。 :)
我正在使用的数据库是我们每晚进行的只读备份。我们备份然后复制备份,这就是我们从中提取统计数据的数据库。除了只有少数人使用它的事实之外,drop 命令还会引发错误。如果确实出现问题,我们只需在当晚进行完整备份而不是差异备份 - 问题就解决了。以上是关于单元格内容作为 Excel 中“WHERE”语句的一部分的主要内容,如果未能解决你的问题,请参考以下文章