繁体   English   中英

如何使用npgsql中的参数在单个命令中更新多行中的列值?

[英]How to update a column value in multiple rows, in a single command, using Parameters in npgsql?

所以我想做的是当用户返回并编辑/更改以前的答案时,用新值更新答案表。 因此,问卷中有20个问题,用户可以填写这些问题,然后将其保存在Questionnaire_ResponseTable中,如果他们返回并更改了答案,我想更新该表。 很简单。

棘手的部分是我想防止SQL注入,因此在构建“ stmnt”时,我会将用户答案作为参数插入(以防他们尝试做一些可疑的事情)。 问题是因为我试图在一个数据库命令中更新所有20行,例如我多次声明“:answer”。 我发现npgsql对所有“:answer”都相同。 因此,当我去修改数据库中的20行时,每行对应一个用户回答的问题。 而不是得到20行带有20个唯一答案,每行最终都使用相同的答案进行更新。

我尝试使用string.format来执行“:answer {0}”之类的操作,以区分“:answer”,但这确实有效,并引发了异常。 我已经通过不使用参数来插入用户提供的答案来使一切正常工作,所以我知道我的posgresql命令有效,问题只是以安全的方式进行,以防止注入。

public void UpdateAnswers(List<string> paramAnswers) {
        List<string> answers = paramAnswers;
        string stmnt = "UPDATE demographic_responses AS dr SET answer = c.answer FROM (values ";

        string updateVals = "";
        for (int i = 1; i <= answers.Count; i++) {
            updateVals = updateVals + string.Format("("+"'"+((App)Application.Current).participantDM.id+"',"+ "'"+i+"'," + ":answer{0}),",i);
        }
        updateVals = updateVals.Substring(0, updateVals.Length-1);

        stmnt = stmnt + updateVals + ") AS c(user_id, question_id, answer) WHERE c.question_id = dr.question_id AND c.user_id = dr.user_id";

        using (NpgsqlConnection conn = PgConnection.GetConnection()) {
            using (NpgsqlCommand cmd = new NpgsqlCommand(stmnt, conn)) {
                for (int i = 0; i < answers.Count; i++) {
                    cmd.Parameters.Add(PgHelpers.ToNpgsqlParameter(DemographicResponseTable.Column.answer));
                    cmd.Parameters[i].Value = answers[i];
                }
                    cmd.ExecuteNonQuery();
            }
        }
    }

像在代码中一样,设置参数而不将其实际发送到数据库(例如,使用ExecuteNonQuery),绝对没有任何效果。 这不是Npgsql特有的行为,而是数据库/ADO.NET的一般行为。

为了帮助您理解,从概念上讲,参数与直接在SQL查询中插入值没有什么不同(当然,除了注入保护和性能优势之外)。

如果您尝试通过不向数据库发送X查询来优化性能,请考虑将架构更改为具有多个答案的单行,其中对问题的回答表示为列而不是行。

Npgsql当前不支持的另一种选择是在一个命令中发送多个UPDATE SQL语句,而不是对每个命令执行ExecuteNonQuery(后者发送SQL并等待响应)。 不幸的是,这目前与参数不兼容(但在Npgsql的下一个主要版本中将受支持)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM