在SQL我们做这样的事情批量插入到可更新
SqlBulkCopy copy = new SqlBulkCopy(sqlCon);
copy.DestinationTableName = strDestinationTable;
copy.WriteToServer(dtFrom);
Blockquote
但在PostgreSQL中,如何执行此操作
我还发现,目前还没有现成的解决方案。也许你可以查看我的另一个答案,我在其中描述了我为这个问题创建的一个小助手,使使用另一个助手变得非常简单:https://stackoverflow.com/a/46063313/6654362我认为这是目前最好的解决方案。我在链接上发布了解决方案,以防帖子死掉。
编辑:我最近遇到了类似的问题,但我们使用的是Postgreql。我想使用有效的保鲜膜,结果是相当困难的。我还没有找到任何适当的免费库这样做在这个数据库。我只找到了这个助手:https://bytefish.de/blog/postgresql_bulk_insert/也在Nuget上。我写了一个小映射器,它自动映射实体框架的方式属性:
public static PostgreSQLCopyHelper<T> CreateHelper<T>(string schemaName, string tableName)
{
var helper = new PostgreSQLCopyHelper<T>("dbo", "\"" + tableName + "\"");
var properties = typeof(T).GetProperties();
foreach(var prop in properties)
{
var type = prop.PropertyType;
if (Attribute.IsDefined(prop, typeof(KeyAttribute)) || Attribute.IsDefined(prop, typeof(ForeignKeyAttribute)))
continue;
switch (type)
{
case Type intType when intType == typeof(int) || intType == typeof(int?):
{
helper = helper.MapInteger("\"" + prop.Name + "\"", x => (int?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type stringType when stringType == typeof(string):
{
helper = helper.MapText("\"" + prop.Name + "\"", x => (string)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type dateType when dateType == typeof(DateTime) || dateType == typeof(DateTime?):
{
helper = helper.MapTimeStamp("\"" + prop.Name + "\"", x => (DateTime?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type decimalType when decimalType == typeof(decimal) || decimalType == typeof(decimal?):
{
helper = helper.MapMoney("\"" + prop.Name + "\"", x => (decimal?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type doubleType when doubleType == typeof(double) || doubleType == typeof(double?):
{
helper = helper.MapDouble("\"" + prop.Name + "\"", x => (double?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type floatType when floatType == typeof(float) || floatType == typeof(float?):
{
helper = helper.MapReal("\"" + prop.Name + "\"", x => (float?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type guidType when guidType == typeof(Guid):
{
helper = helper.MapUUID("\"" + prop.Name + "\"", x => (Guid)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
}
}
return helper;
}
我使用它的方式如下(我有一个名为promise的实体):
var undertakingHelper = BulkMapper.CreateHelper<Model.Undertaking>("dbo", nameof(Model.Undertaking));
undertakingHelper.SaveAll(transaction.UnderlyingTransaction.Connection as Npgsql.NpgsqlConnection, undertakingsToAdd));
我展示了一个带有事务的示例,但它也可以通过从上下文检索的正常连接来完成。undertakingsToAdd是可枚举的普通实体记录,我想将其批量插入数据库。
经过几个小时的研究和尝试,我得到了这个解决方案,正如你所期望的那样,它更快,最终易于使用和免费!我真的建议你使用这个解决方案,不仅是因为上面提到的原因,而且因为它是唯一一个我对Postgresql本身没有问题的解决方案,许多其他解决方案都可以完美地工作,例如SqlServer。
我之前也有同样的问题。到目前为止,似乎还没有“现成的”解决方案。
我读了这篇文章,并在当时构建了一个类似的解决方案,直到今天,这个解决方案仍在有效使用。它基于文本查询,从标准文本中读取文件。它使用ADO。NET Postgre数据提供程序Npgsql。您可以基于数据表创建一个大字符串(或临时文件,这是内存使用的原因),并使用COPY命令将其用作文本查询。在我们的例子中,它比inser teach row快得多。
也许这不是一个完整的解决方案,但可能是一个很好的起点,以及我所知道的一切。:)
您的项目将需要引用以下程序集:Npgsql
。如果此引用在Visual Studio中不可见,则:
CREATE TABLE "OrderHistory"
(
"OrderId" bigint NOT NULL,
"TotalAmount" bigint,
CONSTRAINT "OrderIdPk" PRIMARY KEY ("OrderId")
)
WITH (
OIDS=FALSE
);
ALTER TABLE "OrderHistory"
OWNER TO postgres;
GRANT ALL ON TABLE "OrderHistory" TO postgres;
GRANT ALL ON TABLE "OrderHistory" TO public;
ALTER TABLE "OrderHistory" ALTER COLUMN "OrderId" SET (n_distinct=1);
GRANT SELECT("OrderId"), UPDATE("OrderId"), INSERT("OrderId"), REFERENCES("OrderId") ON "OrderHistory" TO public;
GRANT SELECT("TotalAmount"), UPDATE("TotalAmount"), INSERT("TotalAmount"), REFERENCES("TotalAmount") ON "OrderHistory" TO public;
请务必使用以下指令:
using Npgsql;
using NpgsqlTypes;
在方法中输入以下源代码:
// Make sure that the user has the INSERT privilege for the OrderHistory table.
NpgsqlConnection connection = new NpgsqlConnection("PORT=5432;TIMEOUT=15;POOLING=True;MINPOOLSIZE=1;MAXPOOLSIZE=20;COMMANDTIMEOUT=20;COMPATIBLE=2.2.4.3;DATABASE=test;HOST=127.0.0.1;PASSWORD=test;USER ID=test");
connection.Open();
DataSet dataSet = new DataSet();
NpgsqlDataAdapter dataAdapter = new NpgsqlDataAdapter("select * from OrderHistory where OrderId=-1", connection);
dataAdapter.InsertCommand = new NpgsqlCommand("insert into OrderHistory(OrderId, TotalAmount) " +
" values (:a, :b)", connection);
dataAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("a", NpgsqlDbType.Bigint));
dataAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("b", NpgsqlDbType.Bigint));
dataAdapter.InsertCommand.Parameters[0].Direction = ParameterDirection.Input;
dataAdapter.InsertCommand.Parameters[1].Direction = ParameterDirection.Input;
dataAdapter.InsertCommand.Parameters[0].SourceColumn = "OrderId";
dataAdapter.InsertCommand.Parameters[1].SourceColumn = "TotalAmount";
dataAdapter.Fill(dataSet);
DataTable newOrders = dataSet.Tables[0];
DataRow newOrder = newOrders.NewRow();
newOrder["OrderId"] = 20;
newOrder["TotalAmount"] = 20.0;
newOrders.Rows.Add(newOrder);
DataSet ds2 = dataSet.GetChanges();
dataAdapter.Update(ds2);
dataSet.Merge(ds2);
dataSet.AcceptChanges();
connection.Close();
最初的帖子没有提到绩效要求。要求解决方案必须:
如果要插入大量数据,我建议您查看性能选项。Postgres文档建议您:
COPY
命令有关优化Postgres插入的更多信息,请查看:
此外,还有许多其他因素会影响系统的性能。有关高级介绍,请参阅:
Copy
命令?Postgres
html" target="_blank">函数中,然后该函数可以将数据直接插入到目标中。问题内容: 我正在寻找将数百万个元组批量插入数据库的最有效方法。我正在使用Python,PostgreSQL和psycopg2。 我已经创建了很长一段时间的流氓列表,应该将其插入数据库中,有时还要使用诸如geometric这样的修饰符。 幼稚的方法是对语句列表进行字符串格式化,但是我还了解了三种其他方法: 使用绑定样式进行参数插入 在元组列表上使用,以及 使用将结果写入文件并使用。 似乎第一种方法
我在postgreSQL DB(9.2)中有一个表,其中列类型为json。我正在使用Hibernate,并实现了Tim Fulmer建议的将postgreSQL JSON列映射到Hibernate值类型的代码示例,但我不断得到以下异常: 我不想强制转换表达式,因为不建议使用它。当我使用预先生成的表并且列类型为JSON时,我得到了这个错误。当我更改Hibernate配置以构建表时,我没有得到异常,值
我正在写一个数据挖掘程序,可以批量插入用户数据。 当前SQL只是一个普通的批量插入: 如果发生冲突,如何进行更新?我试过: 但它抛出
问题内容: 这是我在阅读有关jpa批量插入的几个主题之后创建的简单示例,我有2个持久对象User和Site。一个用户可以拥有多个站点,因此我们在这里有一对多的关系。假设我要创建用户并将多个站点创建/链接到用户帐户。考虑到我愿意为Site对象使用批量插入,代码如下所示。 但是,当我运行此代码时(我将hibernate方式用作jpa实现提供程序),我看到以下sql输出: 所以,我的意思是“真实的”批量
问题内容: 我正在使用Python中的MySQLdb模块与数据库进行交互。我遇到的情况是有一个非常大的列表(成千上万个元素),需要将它们作为行插入表中。 我现在的解决方案是生成一个大的语句作为字符串并执行它。 有没有更聪明的方法? 问题答案: 有一种更聪明的方法。 批量插入的问题在于,默认情况下启用了自动提交功能,从而导致每个语句在下一次插入可以启动之前被保存到稳定存储中。 如手册页所述: 默认情
问题内容: 我正在尝试将数据从此链接插入到我的SQL Server https://www.ian.com/affiliatecenter/include/V2/CityCoordinatesList.zip 我创建了表 我正在运行以下脚本来进行批量插入 但是批量插入失败,并出现以下错误 当我使用google时,我发现了几篇文章,指出问题可能出在RowTerminator上,但我尝试了诸如/ n