使用参数的MS Access选择查询失败

时间:2013-01-31 02:16:06

标签: sql ms-access asp-classic

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

我的查询是:

 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”列。

2 个答案:

答案 0 :(得分:0)

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

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

  1. 将您的桌面设计更改为键值对
  2. 根据您提供的条件动态构建您的查询
  3. 对于选项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.
    

答案 1 :(得分:0)

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

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

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

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()
祝你好运。