SQL 对于字符串来说太长了

Posted

技术标签:

【中文标题】SQL 对于字符串来说太长了【英文标题】:SQL too long for String 【发布时间】:2012-03-19 02:24:46 【问题描述】:

我有以下 SQL 要查询。这是一个有效的 SQL。不幸的是,它对于 VBA 中的字符串来说太长了。有人知道运行此查询的解决方法吗?

SQL = "SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id, A.CURR_AGNT_KY, A.incid_ttl_dn " _
    & "FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky) " _
    & "WHERE B.wrkgp_id='" & wrkgp & "' And (A.open_fg = 1 OR A.pend_fg = 1)" _
    & "ORDER BY A.cust_ky, A.curr_agnt_ky ASC"

rs.Open SQL, con, adOpenKeyset

【问题讨论】:

请不要在标题前加上“VBA -”之类的前缀。这就是标签的用途。 VBA 中的字符串可以超过 20 亿个字符。你的字符串真的比那长吗? 这是执行 SQL = 后关注列表中的值。 “选择 A.cust_ky、A.incid_id、A.OPEN_TS、A.CLOSE_TS、A.REC_UPD_TS、B.wrkgp_id、A.CURR_AGNT_KY、A.incid_ttl_dn 来自(MAINTBLS.WF_INCID_F A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky= B.wrkgp_ky) WHERE B.wrkgp_id='POWEBSTE-MTE-PORTAL' 和 (A.ope 仅供参考,您的 SQL 字符串实际上并没有被截断,这只是因为监视窗口的值字段限制为 255 个字符。要验证您的字符串,请将@​​987654323@ 添加到您的代码中并在Immediate 窗口中查看结果。 FWIW 尝试在ORDER BY 子句中的每个字段中添加一个ASC - 即ORDER BY A.cust_ky ASC, A.curr_agnt_ky ASC 您在 ORDER BY " OR A.pend_fg = 1)" _ & "ORDER BY A.cust_ky, A.curr_agnt_ky ASC" 之前缺少一个空格,如果这是您的 SQL 的剪切和粘贴,它将无法在 VBA 中运行。 【参考方案1】:

由于你使用Oracle,你应该使用绑定变量而不是动态SQL,然后在命令对象的参数集合中设置值。它不仅可以防止 SQL 注入,而且可以更好地优化您的查询。

此外,您的 SQL 语句在 order by 子句之前似乎缺少一个空格。这很容易导致你的错误。见下文 - 未经测试,但应该给你的想法。

SQL = "SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id, A.CURR_AGNT_KY, A.incid_ttl_dn " _
    & "FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky) " _
    & "WHERE B.wrkgp_id= :wrkgp And (A.open_fg = 1 OR A.pend_fg = 1) " _
    & "ORDER BY A.cust_ky, A.curr_agnt_ky ASC"

   With cmd
     .ActiveConnection = conn
     .CommandText = SQL
     .CommandType = adCmdText
     .Parameters.Append .CreateParameter(, adVarChar, adParamInput, wrkgp)
   End With

【讨论】:

【参考方案2】:

为查询创建一个视图,类似这样

create view fix_for_broken_vba as
SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id, 
        A.CURR_AGNT_KY, A.incid_ttl_dn FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky)
    WHERE (A.open_fg = 1 OR A.pend_fg = 1)

然后相应地重写查询。

【讨论】:

没有足够的权限来创建视图:(但是谢谢你。我知道这会起作用【参考方案3】:

如果您在 Excel 工作表中使用 VBA,为什么不考虑将 SQL 查询放在文档的受保护单元格中?您甚至可以将它放在文档的隐藏表单中。

类似:

Cells(6, 2).Select
sqlString = Cells(6, 2).Value

我做到了,它对我来说就像一个魅力。

【讨论】:

【参考方案4】:

我已使用以下步骤进行 100 多行查询

在 Excel VBA 中使用长查询

    最初在 SSMS 中创建查询 创建一个名为 SQL Query 的工作表 将查询复制并粘贴到 SQL 查询表中,并删除所有空白行或注释行 在声明语句中加入任何变量

    使用以下宏循环访问 SQL 查询表

    LastRowQ = ThisWorkbook.Sheets("SQL Query").Cells(ThisWorkbook.Sheets("SQL Query").Rows.Count, "B").End(xlUp).Row
    
    Count = 2
    Do Until Count > LastRowQ
    
        SQLQTemp = ThisWorkbook.Sheets("SQL Query").Range("B" & Count)
        SQLQuery = SQLQuery & " " & SQLQTemp
    
        Count = Count + 1
    
    Loop
    
    SQLDatabaseRS.Open SQLQuery
    

【讨论】:

以上是关于SQL 对于字符串来说太长了的主要内容,如果未能解决你的问题,请参考以下文章

free():无效的下一个大小(快)字符串太长了? [重复]

SQLServer问题

如何对文本进行连字符?

超链接可以多长?

JPA 2.0 数据对于列表中的列来说太长

无法创建 NVARCHAR2 > 2000