使用 C# 中的子查询访问数据库 INSERT

Posted

技术标签:

【中文标题】使用 C# 中的子查询访问数据库 INSERT【英文标题】:Access database INSERT with subquery from within C# 【发布时间】:2013-12-24 21:04:50 【问题描述】:

我有两个访问表:用户和分数。 用户表有列:id(自动递增用户 id)、用户名、密码 - id 是主键 分数表有列:id(来自用户的用户 id),highScore - 没有主键

在 C# 方法中,我将用户名和分数作为参数,我想插入到分数表中,以便在 id 字段中是用户的 id,其用户名与提供的用户名匹配。

到目前为止,我尝试过的命令是:

string insertCommand = @"INSERT INTO scores([id], [highScore])
                         VALUES((SELECT id FROM users WHERE username = @username), @score);";

这会抛出:查询输入必须至少包含一个表或查询。

所以在四处探查之后,我发现 Access DB 与通常的 SQL 有点不同,所以我尝试使用 DLookup:

string insertCommand = @"INSERT INTO scores([id], [highScore])
                         VALUES(DLookup(""id"", ""users"", ""username = '@username'""), @score);";

这会通过,但结果行是空的。所以我基本上得到了一个不为 NULL 的空行。

我绝对确定参数包含在命令执行之前添加的值。

command.Parameters.AddWithValue("@username", username);
command.Parameters.AddWithValue("@score", points);

command.CommandText = insertCommand;

command.ExecuteNonQuery();

所以我不知道我在这里做错了什么。我应该这样去吗?我可以以某种方式加入插入内的用户和分数表吗?

【问题讨论】:

你为什么不把它分成两步:一步获取作为参数提供的用户名的id,另一步是插入分数表。这样就避免了子查询问题。 @Ahmad 好吧,我可以,但我决定使用子查询的全部原因是避免将过程分成两个步骤,因为它可以在一个步骤中完成。 你试过""username = @username""而不是""username = '@username'""吗? @GordThompson 是的,我试过了,得到了错误Too few parameters. Expected 1. 【参考方案1】:

如果您不介意稍微更改查询,以下应该可以工作:

string insertCommand = @"INSERT INTO scores (id, highscore)
                         SELECT id,  @highScore FROM users WHERE username = ?;";

这是测试中为我工作的代码块:

var highScore = 99;
var username = "johndoe";
OleDbConnection con = new OleDbConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString());

string insertCommand = @"INSERT INTO scores (id, highscore)
                        SELECT id, @highScore FROM users WHERE username = @username;";

OleDbCommand cmd = new OleDbCommand(insertCommand, con);
cmd.Parameters.AddWithValue("@highScore", highScore);
cmd.Parameters.AddWithValue("@username", username);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

【讨论】:

那行得通。习惯了 mysql 并使用INSERT INTO x(col1, col2,..) VALUES(val1, val2,..),所以我从没想过像那样使用 SELECT。那谢谢啦。不过有一件事。我真的不喜欢你如何连接 highScore。特别是因为您已将其定义为 var。如果有新手来做这件事,他不能通过使用纯连接使他的代码容易受到 SQL 注入吗? 你确定吗?因为我的插入命令看起来像这样 string insertCommand = @"INSERT INTO scores (id, highscore) SELECT id, @score FROM users WHERE username = @username;"; ,并且可以正常工作。 你说得对,这行得通……我一定是和别的东西混在一起了。

以上是关于使用 C# 中的子查询访问数据库 INSERT的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 中的数据库中获取最后一个 id

MySQL INSERT 在同一张表上使用带有 COUNT() 的子查询

在MS访问中的子表单上显示查询结果

使用java和SQL查询INSERT INTO将新记录插入MS访问[关闭]

访问不允许SQL-Server列中的空值的INSERT或UPDATE(访问运行时错误3162)

如何在C#中实现OPC数据访问