VBA 列限制中的 SQL 命令

Posted

技术标签:

【中文标题】VBA 列限制中的 SQL 命令【英文标题】:SQL command in VBA column limitation 【发布时间】:2020-08-17 01:43:22 【问题描述】:

在 VBA 代码中,一个sqlcommand 可以带入多少列有限制吗?我的代码很长,但用于确保我始终从正确的数据库中提取。当用户在数据库中选择时,m2mdata02 将替换为代码CatalogM2M。要带入的总列数是 7 个表中的 23 列。

Sqlcommand = “select left(m2mdata02.dbo.jomast.fjobno,5) as job, m2mdata02.dbo.jomast.fjobno, m2mdata02.dbo.jomast.fpartno, m2mdata02.dbo.jomast.fstatus, m2mdata02.dbo.jomast.fact_rel, m2mdata02.dbo.jomast.fddue_date, m2mdata02.dbo.jomast.fprodcl, m2mdata02.dbo.jomast.frel_dt, m2mdata02.dbo.jomast.frouting, m2mdata02.dbo.inmastx.fpartno, m2mdata02.dbo.inmastx.fdescript, m2mdata02.dbo.inmastx.fprice, m2mdata02.dbo.somast.fsono, m2mdata02.dbo.somast.fcompany, m2mdata02.dbo.somast.fcustpono, m2mdata02.dbo.aritem.fcinvoice, m2mdata02.dbo.aritem.fprice, m2mdata02.dbo.aritem.fcsono, m2mdata02.dbo.armast.fcinvoice, m2mdata02.dbo.armast.finvdate, m2mdata02.dbo.shmast.fshipdate, m2mdata02.dbo.shmast.fshipno, m2mdata02.dbo.shmast.fcsono
from m2mdata02.dbo.jomast
left join m2mdata02.dbo.inmastx on m2mdata02.dbo.inmastx.fpartno = m2mdata02.dbo.jomast.fpartno
left join m2mdata02.dbo.somast on m2mdata02.dbo.somast.fsono = m2mdata02.dbo.jomast.fsono 
left join m2mdata02.dbo.aritem on m2mdata02.dbo.aritem.FCSONO = m2mdata02.dbo.jomast.fsono
left join m2mdata02.dbo.armast on m2mdata02.dbo.armast.fcinvoice = m2mdata02.dbo.aritem.fcinvoice
left join m2mdata02.dbo.shmast on m2mdata02.dbo.shmast.fcsono = m2mdata02.dbo.somast.fsono
where m2mdata02.dbo.jomast.fprodcl = 'FG11' order by m2mdata02.dbo.jomast.fjobno”

【问题讨论】:

SQL Server 中每个SELECT 的最大列数为 4096。我怀疑 VBA 中是否存在实际限制。 你问是因为你有问题吗? 【参考方案1】:

根据MSDN docs,VBA 中String 类型的字符限制约为二十亿(2^31)个Unicode 字符。您的 SQL 查询远不及该限制。如果使用 ADO 将 Excel VBA 连接到数据库,这里的服务器引擎是 SQL Server 决定列限制,并且 23 再次不在maximum capacity 附近。

但是,请考虑使用表格别名来减少字符,避免重复三个句点标识符,并整体提高可读性甚至可维护性,因为您可以更轻松地为每个用户选择调整表格引用。

select left(j.fjobno,5) as job
       , j.fjobno
       , j.fpartno
       , j.fstatus
       , j.fact_rel
       , j.fddue_date
       , j.fprodcl
       , j.frel_dt
       , j.frouting
       , i.fpartno
       , i.fdescript
       , i.fprice
       , so.fsono
       , so.fcompany
       , so.fcustpono
       , ari.fcinvoice
       , ari.fprice
       , ari.fcsono
       , arm..fcinvoice
       , arm..finvdate
       , sh.fshipdate
       , sh.fshipno
       , sh.fcsono 
       
from m2mdata02.dbo.jomast j
left join m2mdata02.dbo.inmastx i on i.fpartno = j.fpartno 
left join m2mdata02.dbo.somast so on so.fsono = j.fsono 
left join m2mdata02.dbo.aritem ari on ari.FCSONO = j.fsono 
left join m2mdata02.dbo.armast arm on arm..fcinvoice = ari.fcinvoice 
left join m2mdata02.dbo.shmast sh on sh.fcsono = so.fsono 
where j.fprodcl = 'FG11' 
order by j.fjobno

顺便说一句,对于很长的查询,避免在 VBA 中使用行连接和双引号构建字符串,并直接从格式化的 SQL 文本文件中读取:

Dim strSQL As String

' READ SQL QUERY FROM FILE
With CreateObject("Scripting.FileSystemObject")
      strSQL = .OpenTextFile("C:\path\to\my\SQL\Query.sql", 1).readall
End With

' REPLACE DB IN STRING
strSQL = Replace(strSQL, "m2mdata02", "someotherdb")

【讨论】:

优秀的分数。我会考虑创建一个视图。与您的文本文件方法类似,我将查询存储在专用用户表单的文本框中。这使我可以像m2mdata02Query = QueryForm.M2mdata02.Value 一样访问它们。使用SQL Formatter 也大大提高了可读性。 如何将数据库设置为动态数据库?我正在调用一个名为“CatalogM2M”的公众,它是根据用户的输入设置的。用户将选择一种模式,将我的 SQL 的其余部分定向到特定数据库。 您是否看到底部 VBA 代码块中的 Replace 行?让用户输入替换"someotherdb" 我在我的代码块中使用该行,但想引用我建立的 catalogm2m dim 作为数据库名称。用户将不知道要参考的正确数据库。我已经尝试了一些还没有奏效的方法。 你能问一个新的问题吗?不要让未来的读者混淆标题和内容。

以上是关于VBA 列限制中的 SQL 命令的主要内容,如果未能解决你的问题,请参考以下文章

SQL 错误访问 2010 VBA 更新命令

VBA/SQL 参数化查询 - 字段列表中的未知列

访问 VBA SQL 更新命令

MS Access VBA:基于查询结果的 VBA 命令

Python中的SQL更新命令找不到列并且数据库被锁定

使用 ADO.NET 命令向 VB 中的 SQL 表添加列