从选择查询+变量值插入表

Posted

技术标签:

【中文标题】从选择查询+变量值插入表【英文标题】:Insert into table from select query + variables values 【发布时间】:2014-01-29 15:31:18 【问题描述】:

我想在表 tb2(QuestionID、QuestionStem、UserID、ExamID)中插入一组从表 tb1(QuestionID、QuestionStem)中随机选择的行以及两列 UserID、ExamID 的值,这些列对于一次插入是固定的询问。我已在 webmatrix 中尝试过此查询,但在插入查询语句中出现 @ 不应位于此位置的错误:

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @UserID, @ExamID FROM tb2");

感谢任何帮助。我正在使用 webmatrix 3.0 来构建我的应用程序。 请注意,插入后的 UPDATE 语句将不起作用,因为将有同时存在的用户,我想根据每个用户的 UserID 和 ExamID 显示选定的行。

【问题讨论】:

【参考方案1】:

您无法在 Webmatrix 中使用单个参数化查询来完成您的任务,而且在我看来,创建连接参数的查询并不是一个好的解决方案。

更好的选择是从表 t1 中提取您需要的记录,并使用 foreach 循环将它们一一插入:

@
    var userId = 25;
    var examId = 32;
    var sql1 = "SELECT TOP 10 QuestionID, QuestionStem FROM t1 ORDER BY NEWID()";
    var sql2 = @"INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) 
        VALUES (@0, @1, @2, @3)";
    var db = Database.Open("yourDb");
    var data = db.Query(sql1);
    foreach (var row in data)
        db.Execute(sql2, row.QuestionID, row.QuestionStem, userId, examId);
    

已编辑

如果性能是一个真正的问题,也许最好的解决方案是将数据从 Sql Server Compact 迁移到 Sql Server Express。

在这种环境下,您可以创建像

这样的存储过程
CREATE PROCEDURE AddQuestions @UserID int, @ExamID int
    AS
    INSERT INTO dbo.tb2 (QuestionID, QuestionStem, UserID, ExamID) 
    SELECT TOP 10 QuestionID, QuestionStem, @UserID AS UserID, @ExamID AS ExamID
    FROM dbo.t2 ORDER BY NEWID()
GO

并在 WebMatrix 中调用它:

@
    var userId = 14;
    var examId = 16;
    var db = Database.Open("yourDb");
    var data = db.Execute("EXEC AddQuestions @UserID = @0, @ExamID = @1", 
       userId, examId);

【讨论】:

不同意您的回答,因为我理解避免串联的愿望,但这种方法比我的回答效率低一个数量级。只要您了解风险并在更一般的意义上知道您在做什么,我认为将类型安全整数连接到命令中没有问题。对于流量很少的网站上只有 10 行,这种方法更好,因为它可以避免“危险”的地面,但如果 sql1 选择数千行,则可能需要几秒钟而不是几毫秒才能完成。 @Polynomial,我同意你的观点,我的解决方案比你的效率低​​,但是,如果性能是一个问题,也许 Sql Server Compact 不是正确的选择。我已经编辑了我的答案。 一个公平的观点,您的编辑值得一票。公平地说,这个问题并没有具体说明他们使用的是什么 SQL 版本(我知道你可以从我的答案的评论中推断出来,但问题本身就足够笼统了),我会说它总是值得通过每种方法的相对优缺点。程序员能够做出明智的决定总是更好。 感谢您非常有建设性的 cmets。【参考方案2】:

如果我理解正确,您可以对这两个参数使用编号的序数。像这样,但设置变量以使用您的数据当然是适当的:

var userId = 0;
var examId = 0;
db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @0, @1 FROM tb1", userId, examId);

您还提到您希望随机选择来自tb1 的行。您可以通过将ORDER BY NEWID() 添加到查询中SELECT 语句的末尾来实现此目的:

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @0, @1 FROM tb1 ORDER BY NEWID", userId, examId);

如果您只想将其限制为多行(例如,十行):

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT TOP 10 QuestionID, QuestionStem, @0, @1 FROM tb1 ORDER BY NEWID", userId, examId);

【讨论】:

它没有用。错误消息:此位置不允许有参数。确保“@”符号位于有效位置或此 SQL 语句中的参数完全有效。说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。异常详细信息:System.Data.SqlServerCe.SqlCeException:此位置不允许参数。确保“@”符号位于有效位置或此 SQL 语句中的参数完全有效。 我猜你可以直接将参数连接到字符串中,注意避免注入黑客向量(这应该很容易,因为它们都是整数值)。

以上是关于从选择查询+变量值插入表的主要内容,如果未能解决你的问题,请参考以下文章

平台内置业务表变量值设置

在 GraphQL 查询中插入变量值

是否可以创建一个同时插入变量值和表字段的追加查询?

是否可以将变量值添加到选择查询结果 php pdo

如何将变量值与 select 语句的结果一起放入 sql 表中?

通过android和JDBC将变量值插入Sql server