【问题标题】:Void out parameter of SQL query if empty cell selection from Excel - VBA如果从 Excel 中选择空单元格,则取消 SQL 查询的参数 - VBA
【发布时间】:2021-07-16 20:34:25
【问题描述】:

我想知道如果单元格值留空,是否有办法使部分字符串查询无效,而不是使用嵌套的 If 语句。

细胞结构如下:

来自这些参数的单元格值将被传递到查询数据库的 vba 代码中。 理想情况下,我不想为每种选择类型创建单独的查询——我已经让它从位置动态查询。我想扩展查询以包括开始、结束、值 >、值

SELECT * 
from database 
WHERE location = 'cell_loc' 
AND Value >= 'cell_value' 
AND Value <= 'cell_value' 
AND Start >= 'cell_date' 
AND End <= 'cell_date'

现在假设 Start 留空,这意味着我想从数据库中的第一个数据点进行查询:

我可以编写一个嵌套的 if 来处理这个问题,但想知道是否有一种方法可以取消查询参数,以便我可以将单个查询提供给数据库,并根据单元格数据更改不同的参数?

类似的东西:

SELECT * 
from database 
WHERE location = 'cell_loc' 
AND Value >= 'cell_value' 
AND Value <= 'cell_value' 
AND Start >= 'cell_date' --> this would be voided out
AND End <= 'cell_date'

【问题讨论】:

  • 看一下 coalesce() 函数。 stackoverflow.com/questions/17104329/…
  • 通常您会通过构建 SQL 来做到这一点,根据需要添加每个 where 子句,具体取决于您的查询单元格是否被填充。
  • @SamM hm,看起来只返回列表中的第一个空值。如果填充了单元格值,我仍然想返回整个选择。为了更清楚,“单元格值”是我的查询参数,而不是我查询的数据库值。
  • @TimWilliams 你有一个查询单元的例子吗?我不需要它们,可以复制,但如果你想将该条件添加到上面查询中的 Start 参数中。

标签: mysql sql excel vba


【解决方案1】:

使用 coalesce() 函数,您可以在 WHERE 子句中放置一个相等条件。这是处理数据中的空参数或空值的常用 SQL 技巧。

SELECT * 
from database 
WHERE location = 'cell_loc' 
AND Value >= 'cell_value' 
AND Value <= 'cell_value' 
AND (Start >= 'cell_date' OR Start = coalesce('cell date', Start))
AND End <= 'cell_date'

【讨论】:

  • 这看起来正是我正在寻找的。我对其进行了测试 - 当有一个值时它工作得很好!但是,如果 excel 值留空,我会收到不正确的语法错误。当单元格留空时,使用 Debug.Print 查询将返回 SELECT ZONE, DATE, GASPRICE FROM ERCOT.GAS WHERE ZONE='NGPL-TxOk' AND (GASPRICE &gt;= OR GASPRICE = coalesce(, GASPRICE)),由于值留空,我可以看到有错误。
  • 只是为了给你更多的工作信息。如果我包含一个值,查询将看起来像SELECT ZONE, DATE, GASPRICE FROM ERCOT.GAS WHERE ZONE='NGPL-TxOk' AND (GASPRICE &gt;=4.8 OR GASPRICE = coalesce(4.8, GASPRICE)),因为包含了一个值,所以它显然可以工作。仍然可以使用合并来绕过这个吗?
【解决方案2】:

这是一个非常基本的例子:

Sub Tester()
    Dim sWhere As String, sql As String
    
    sql = "Select * from myTable "
    
    sWhere = ""
    BuildWhere sWhere, "id = <v>", Range("A5")
    BuildWhere sWhere, "pName = '<v>'", Range("B5")
    BuildWhere sWhere, "pDate > '<v>'", Range("C5")
    
    If Len(sWhere) > 0 Then
        sql = sql & " where " & sWhere
        Debug.Print sql
        'run query
    Else
        'don't run if no criteria ?
    End If

End Sub

'add a where clause only if `c` has a value
Sub BuildWhere(ByRef sWhere As String, test As String, c As Range)
    Dim v
    v = Trim(c.Value)
    If Len(v) > 0 Then
        If Len(sWhere) > 0 Then sWhere = sWhere & vbLf & " and "
        sWhere = sWhere & Replace(test, "<v>", v)
    End If
End Sub

【讨论】:

  • 这只是确定 c 是否有使用长度的值吗?不错,我在 Python 中使用了这个技巧——但对 VBA 有点陌生。
  • 是的,只是检查长度以查看是否有任何内容。在处理用户输入时总是值得投入Trim()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
相关资源
最近更新 更多