使用 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的主要内容,如果未能解决你的问题,请参考以下文章
MySQL INSERT 在同一张表上使用带有 COUNT() 的子查询
使用java和SQL查询INSERT INTO将新记录插入MS访问[关闭]