【问题标题】:MS Access select query using parameters fails使用参数的 MS Access 选择查询失败
【发布时间】:2013-01-31 22:12:32
【问题描述】:

我使用 Access DB 作为经典 asp 网页的后端。我正在创建一个使用参数的已保存查询。我在 Access 2000 的查询生成器中测试。字段都是文本,默认值为 NULL,[in_b]s 允许零长度,其中有 9 个,命名为 B160、B80、B40、B30 等。

我的查询是:

 SELECT COUNT([in_b]) AS BCnt FROM tblScore 
 WHERE UCALL=[in_call] and NOT ISNULL([in_b]);

这将返回给定 UCALL 的所有行的计数。如果我将 2[in_b] 中的任何一个更改为实际的列名,查询会给出我想要的(在本例中为 0),但是我必须运行 9 个查询。

表格示例

Call  Zone B160   B80  B40
NF4L   1    NULL   X    NULL
NF4L   6    Null  Null  NULL
NF4L   20     X     X   Null
WA4B   2    NULL  NULL   X

If in_call is NF4L and in_b is B160, I expect 1
If in_call is NF4L and in_b is B80,  I expect 2
If in_call is NF4L and in_b is B40,  I expect 0

目标是对给定调用的所有非空“B”列进行计数。

【问题讨论】:

  • 你能发布一些示例数据和想要的结果吗?

标签: sql ms-access asp-classic


【解决方案1】:

在这种情况下,您使用参数 ([in_b]) 作为对列的引用,而不是实际数据值。我认为这种设计不会走得太远。

除了构建 9 个不同的查询(不要这样做!)之外,您还可以尝试其他两个选项:

  1. 将您的表格设计更改为更多的键值对
  2. 根据您提供的条件动态构建查询

对于选项 1,您可以将表格更改为如下所示:

Call | Zone | BField | BFieldValue
NF4L | 1    | B80    | X
NF4L | 1    | B160   | NULL
NF4L | 1    | B40    | NULL
NF4L | 6    | B160   | NULL
NF4L | 6    | B80    | NULL
NF4L | 6    | B40    | NULL
NF4L | 20   | B160   | X
NF4L | 20   | B80    | X
NF4L | 20   | B40    | NULL
...

您的查询可能如下所示:

SELECT BField, COUNT([BFieldValue]) AS BCnt 
FROM tblScore 
WHERE UCALL=[in_call] and [BFieldValue] IS NOT NULL
GROUP BY BField;

此选项是两者中可扩展性更强的选项。如果您需要在某些时候添加额外的“BFields”,这样做是微不足道的,但代价是必须重新设计表格,以便将数据添加到表格中。

选项 2 是在运行时动态构建查询,以便您可以根据您概述的条件替换实际的列名。例如:

Dim SQL as String
Dim BField as String
Dim InCall as String

'These would typically be passed in, not hardcoded as they are here
Set InCall = "NF4L"
Set BField = "B160"

SET SQL = "SELECT Count([" & BField & "] FROM tblScore WHERE [Call] ='" & InCall & "' AND NOT ISNULL([" & BField & "]);"

'From here, either open up a recordset based on this SQL or create a new QueryDef object and execute it.

【讨论】:

    【解决方案2】:

    我知道使用 SQL Server,您可以传递参数并使用 CASE 语句,如下所示:

    SELECT COUNT(*) 
    FROM Test
    WHERE CASE 
       WHEN @col = 'col1'
       THEN col1 
       WHEN @col = 'col2' 
       THEN col2 END IS NOT NULL
    

    其中@col 是传入的参数。我认为您可以在 MS Access 中使用 IIF 执行此操作——试一试:

    SELECT COUNT(*) 
    FROM Test
    WHERE NOT ISNULL(IIF(@col = 'col1', col1, IIF(@col = 'col2', col2, ...))
    

    或者,您可以使用动态 SQL 执行此服务器端,但请确保使用参数化查询。这是一个很好的例子:

    Const ad_nVarChar = 202
    Const ad_ParamInput = 1
    
    strSQL = "SELECT Count(*) FROM tblScore WHERE [Call] = ? AND NOT ISNULL(?); "
    
    Set cmd = Server.CreateObject("ADODB.Command")    
    cmd.ActiveConnection = connStr
    cmd.CommandText = strSQL
    cmd.CommandType = adCmdText
    cmd.Parameters(0) = "NF4L"
    cmd.Parameters(1) = "B160"
    
    Set rst = cmd.Execute()
    

    祝你好运。

    【讨论】:

    • 感谢您,感谢您的时间和精力。在阅读您的答案之前,我将表格设计更改为只有 Call、Zone 和 Band 的列,用 B160、B80 等值填充 Band。
    猜你喜欢
    • 2010-09-10
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多