使用子查询访问数据库UPDATE表

时间:2013-12-25 16:01:10

标签: asp.net ms-access

我永远不应该期望知道mySQL我会使用Access安全。

我有两个表:用户和分数 users表包含:id(自动增量主键),用户名,密码等。 scoers表包含:id(number - users.id的外键),highScore

我之前已经向INSERT命令请求了帮助,现在它可以正常工作。现在我遇到类似UPDATE命令的问题。

非工作命令如下所示:

string updateCommand = @"UPDATE scores
                         SET
                         id = (SELECT id FROM users WHERE username = @username),
                         highScore = @score
                         WHERE highScore = (SELECT MIN(highScore) FROM scores);";

抛出一个:Operation must use an updateable query.

为了理顺我在这里要完成的事情:我在插入高分,直到我在表中达到10分,之后不是添加任何新分数并且不必要地填满数据库我决定它是使用UPDATE“覆盖”当前最低分数更为明智。

我提供了一个用户名和高分,因为scores表只包含id我需要达到当前用户的id,这就是第一个子查询正在做的事情,第二个子查询在WHERE子句中指定要替换的分数(尽管如果有多个分数最低的人可能存在错误,那么任何想法如何解决?)

我也试过像这样使用OUTER RIGHT JOIN:

string updateCommand = @"UPDATE scores
                            OUTER RIGHT JOIN users ON scores.id = users.id
                            SET
                            scores.id = users.id,
                            scores.highScore = @score
                            WHERE (highScore = (SELECT MIN(highScore) FROM scores)) AND (username = @username);";

没有运气(我得到通用Syntax error in UPDATE statement.)。

浏览网页我发现我可能“不能”在UPDATE语句中使用子查询,但我似乎发现了有关此问题的相互矛盾的意见。

我也尝试使用DLookup函数代替子查询,如:

@"...
id = DLookup(""id"", ""users"", ""username = @username""),
...
WHERE highScore = DLookup(""MIN(highScore)"", ""scores"");";

elipses表示与上述代码相同的无关代码。

另外作为最后的手段,我尝试分为多个查询但是userId查询看起来像这样:

string userIdQuery = "SELECT id FROM users WHERE username = @username"

似乎返回一个空值,在我完成此操作后尝试使用变量userId时,我接收到NullReferenceException(Object reference not set to an instance of an object.)判断:

int userId = 0;
userId = (Int32)command.ExecuteScalar();

我应该得到一个整数但是我觉得我得到一个null。获得最小高分的几乎相同的查询完美无缺,int变量用正确的值填充,所以我假设hte问题在查询本身中以某种方式。我试过在@username参数周围添加单引号,假设它可能没有识别字符串,但似乎不是它。

Phew ..花了一些时间来写这篇文章。任何人都有任何关于如何使这一切工作的想法?如果您需要更多信息,请告诉我们。

1 个答案:

答案 0 :(得分:1)

所以在经历了一些乱七八糟的事情后,我发现了我的麻烦的原因。不好的一面是我增加了代码量,以便尽可能地避免子查询,因为至少根据我的经验,Access并不真的喜欢在UPDATE或{{1}中使用子查询命令。

我首先做的是将命令分成3个单独的命令:

  • INSERT - 获取分数用户的ID 我正在加入数据库。

  • "SELECT id FROM users WHERE username = ?;" - 获得id,高分 和输入时间良好的时间,当前在高分列表中的最低分数。感谢HansUp的建议,我使用了@"SELECT scores.id, scores.highScore, scores.dateTime FROM scores WHERE (((scores.highScore)=DMin(""highScore"",""scores"")));"函数而不是使用DMin的子查询来避免MIN错误。无关的括号是由于Access,因为这个命令是由Access查询设计者生成的,我太害怕改变任何东西,以免打破它。

  • Must use an updateable query - 更新命令本身,除了它采用先前提取的数据并将其用作命令的值之外,这里不多说。

我注意到的一件事是,即使我使命令正常工作,@"UPDATE scores SET scores.id = ?, scores.highScore = ?, scores.[dateTime] = Now() WHERE (((scores.id)=?) AND ((scores.highScore)=?) AND ((scores.dateTime)=?));"总会返回0行受影响。在探讨之后,我发现ASP.NET / C#中命令的命名参数并不总是有效,而应该使用.ExecuteNonQuery()代替。这有点不方便,但我不能抱怨太多。