在npgsql中准备语句和批处理

时间:2019-02-14 13:28:46

标签: npgsql

文档(https://www.npgsql.org/doc/prepare.html#simple-preparation)中的Simple Preparation示例显示了在准备命令后设置参数的示例。

var cmd = new NpgsqlCommand(...);
cmd.Parameters.Add("param", NpgsqlDbType.Integer);
cmd.Prepare();
// Set parameters
cmd.ExecuteNonQuery();
// And so on

问题

  1. 如何设置参数?
  2. 如果使用了指定AddWithValue的{​​{1}}方法,是否可以使用Add而不是AddWithValue(String, NpgsqlDbType, Object)-文档说“不支持设置值” ?
  3. 如果同一命令中存在多个语句,这将如何工作?

此答案(https://stackoverflow.com/a/53268090/10984827)表明可以一起准备单个字符串中的多个命令,但不清楚如何创建此CommandText字符串。


编辑:我想我快到了,但是我不确定如何创建和执行批处理的查询字符串。这是我使用StringBuilder构建批处理查询的幼稚尝试。这行不通。如何正确执行此操作?

NpgsqlDbType

1 个答案:

答案 0 :(得分:0)

1)只需捕获从Add()返回的NpgsqlParameter,然后设置其Value属性:

var p = cmd.Parameters.Add("p", NpgsqlDbType.Integer);
cmd.Prepare();
p.Value = 8;
cmd.ExecuteNonQuery();

2)您可以以相同的方式使用AddWithValue(),但是如果您要准备命令以使其多次重复使用,那就没有意义了。这个想法是,您首先添加不带值的参数,然后准备,然后执行几次,每次设置值。

3)您可以准备多语句命令。现在一切正常,命令中的所有语句将共享相同的参数列表(位于NpgsqlCommand上)。因此,保持相同的模式:使用SQL和参数创建命令,进行准备,然后设置参数值并执行。得益于性能提升,命令中的每个单独语句都将准备运行。

以下是具有两个语句的批处理的示例:

cmd.CommandText = "INSERT INTO tabletest1 (value1,value2) VALUES (@v1,@v2); INSERT INTO tabletest1 (value1, value2) VALUES (@v3,@v4)";
var v1 = cmd.Parameters.Add("v1", NpgsqlDbType.Integer);
var v2 = cmd.Parameters.Add("v2", NpgsqlDbType.Integer);
var v3 = cmd.Parameters.Add("v3", NpgsqlDbType.Integer);
var v4 = cmd.Parameters.Add("v4", NpgsqlDbType.Integer);
cmd.Prepare();

while (...) {
    v1.Value = ...;
    v2.Value = ...;
    v3.Value = ...;
    v4.Value = ...;
    cmd.ExecuteNonQuery();
}

但是,如果目标是有效插入大量数据,consider using COPY instead-将比批量插入还要快。

最后,要完成图片,对于INSERT语句,您可以在单个语句中包括多个行:

INSERT INTO tabletest1 (value1, value2) VALUES (1,2), (3,4)

您也可以再次参数化实际值,并准备此命令。这类似于批处理两个INSERT语句,并且应更快(尽管仍比COPY慢)。