symfony2中有没有办法实现批量添加数据到数据库表中

symfony2中有没有办法实现批量添加数据到数据库表中,第1张

一、针对批量插入数据,如果量不是太多,可以多条SQL语句运行就可以了,

类似下面的语句,当然可以使用excel 编辑后,复制到查询器中运行,

insert into table(a,b) values('1','a')

insert into table(a,b) values('2','b')

insert into table(a,b) values('3','c')

二、大量数批量插入,即数据表的移植,数据备份转换之类的,就需要工具,比如MSSQL的DTS工具,pb的数据通道 等等。这里介绍一下 DTS工具。

1、在SQL安装目录下开启导入和导出数据,即DTS。

2、选择一个批量的数据,可以是表,也可以是带分隔符的文件,或excel文档之类,如图中选择,导入的格式

3、选择导入的目标

4、选择导入方式

5具体的导入规则

一、SqlServer数据批量插入

SqlServer的批量插入很简单,使用SqlBulkCopy就可以,以下是该类的实现:

复制代码

/// <summary>

/// 为 SystemDataSqlClient 提供的用于批量 *** 作的方法。

/// </summary>

public sealed class MsSqlBatcher : IBatcherProvider

{

/// <summary>

/// 获取或设置提供者服务的上下文。

/// </summary>

public ServiceContext ServiceContext { get; set; }

/// <summary>

/// 将 <see cref="DataTable"/> 的数据批量插入到数据库中。

/// </summary>

/// <param name="dataTable">要批量插入的 <see cref="DataTable"/>。</param>

/// <param name="batchSize">每批次写入的数据量。</param>

public void Insert(DataTable dataTable, int batchSize = 10000)

{

CheckerArgumentNull(dataTable, "dataTable");

if (dataTableRowsCount == 0)

{

return;

}

using (var connection = (SqlConnection)ServiceContextDatabaseCreateConnection())

{

try

{

connectionTryOpen();

//给表名加上前后导符

var tableName = DbUtilityFormatByQuote(ServiceContextDatabaseProviderGetService<ISyntaxProvider>(), dataTableTableName);

using (var bulk = new SqlBulkCopy(connection, SqlBulkCopyOptionsKeepIdentity, null)

{

DestinationTableName = tableName,

BatchSize = batchSize

})

{

//循环所有列,为bulk添加映射

dataTableEachColumn(c => bulkColumnMappingsAdd(cColumnName, cColumnName), c => !cAutoIncrement);

bulkWriteToServer(dataTable);

bulkClose();

}

}

catch (Exception exp)

{

throw new BatcherException(exp);

}

finally

{

connectionTryClose();

}

}

}

}

SqlBulkCopy的ColumnMappings中列的名称受大小写敏感限制,因此在构造DataTable的时候应请注意列名要与表一致。

以上没有使用事务,使用事务在性能上会有一定的影响,如果要使用事务,可以设置SqlBulkCopyOptionsUseInternalTransaction。

复制代码

二、Oracle数据批量插入

SystemDataOracleClient不支持批量插入,因此只能使用OracleDataAccess组件来作为提供者。

View Code

以上最重要的一步,就是将DataTable转为数组的数组表示,即object[][],前数组的上标是列的个数,后数组是行的个数,因此循环Columns将后数组作为Parameter的值,也就是说,参数的值是一个数组。而insert语句与一般的插入语句没有什么不一样。

三、SQLite数据批量插入

SQLite的批量插入只需开启事务就可以了,这个具体的原理不得而知。

View Code

四、MySql数据批量插入

复制代码

/// <summary>

/// 为 MySqlData 组件提供的用于批量 *** 作的方法。

/// </summary>

public sealed class MySqlBatcher : IBatcherProvider

{

/// <summary>

/// 获取或设置提供者服务的上下文。

/// </summary>

public ServiceContext ServiceContext { get; set; }

/// <summary>

/// 将 <see cref="DataTable"/> 的数据批量插入到数据库中。

/// </summary>

/// <param name="dataTable">要批量插入的 <see cref="DataTable"/>。</param>

/// <param name="batchSize">每批次写入的数据量。</param>

public void Insert(DataTable dataTable, int batchSize = 10000)

{

CheckerArgumentNull(dataTable, "dataTable");

if (dataTableRowsCount == 0)

{

return;

}

using (var connection = ServiceContextDatabaseCreateConnection())

{

try

{

connectionTryOpen();

using (var command = ServiceContextDatabaseProviderDbProviderFactoryCreateCommand())

{

if (command == null)

{

throw new BatcherException(new ArgumentException("command"));

}

commandConnection = connection;

commandCommandText = GenerateInserSql(ServiceContextDatabase, command, dataTable);

if (commandCommandText == stringEmpty)

{

return;

}

commandExecuteNonQuery();

}

}

catch (Exception exp)

{

throw new BatcherException(exp);

}

finally

{

connectionTryClose();

}

}

}

/// <summary>

/// 生成插入数据的sql语句。

/// </summary>

/// <param name="database"></param>

/// <param name="command"></param>

/// <param name="table"></param>

/// <returns></returns>

private string GenerateInserSql(IDatabase database, DbCommand command, DataTable table)

{

var names = new StringBuilder();

var values = new StringBuilder();

var types = new List<DbType>();

var count = tableColumnsCount;

var syntax = databaseProviderGetService<ISyntaxProvider>();

tableEachColumn(c =>

{

if (namesLength > 0)

{

namesAppend(",");

}

namesAppendFormat("{0}", DbUtilityFormatByQuote(syntax, cColumnName));

typesAdd(cDataTypeGetDbType());

});

var i = 0;

foreach (DataRow row in tableRows)

{

if (i > 0)

{

valuesAppend(",");

}

valuesAppend("(");

for (var j = 0; j < count; j++)

{

if (j > 0)

{

valuesAppend(", ");

}

var isStrType = IsStringType(types[j]);

var parameter = CreateParameter(databaseProvider, isStrType, types[j], row[j], syntaxParameterPrefix, i, j);

if (parameter != null)

{

valuesAppend(parameterParameterName);

commandParametersAdd(parameter);

}

else if (isStrType)

{

valuesAppendFormat("'{0}'", row[j]);

}

else

{

valuesAppend(row[j]);

}

}

valuesAppend(")");

i++;

}

return stringFormat("INSERT INTO {0}({1}) VALUES {2}", DbUtilityFormatByQuote(syntax, tableTableName), names, values);

}

/// <summary>

/// 判断是否为字符串类别。

/// </summary>

/// <param name="dbType"></param>

/// <returns></returns>

private bool IsStringType(DbType dbType)

{

return dbType == DbTypeAnsiString || dbType == DbTypeAnsiStringFixedLength || dbType == DbTypeString || dbType == DbTypeStringFixedLength;

}

/// <summary>

/// 创建参数。

/// </summary>

/// <param name="provider"></param>

/// <param name="isStrType"></param>

/// <param name="dbType"></param>

/// <param name="value"></param>

/// <param name="parPrefix"></param>

/// <param name="row"></param>

/// <param name="col"></param>

/// <returns></returns>

private DbParameter CreateParameter(IProvider provider, bool isStrType, DbType dbType, object value, char parPrefix, int row, int col)

{

//如果生成全部的参数,则速度会很慢,因此,只有数据类型为字符串(包含'号)和日期型时才添加参数

if ((isStrType && valueToString()IndexOf('\'') != -1) || dbType == DbTypeDateTime)

{

var name = stringFormat("{0}p_{1}_{2}", parPrefix, row, col);

var parameter = providerDbProviderFactoryCreateParameter();

parameterParameterName = name;

parameterDirection = ParameterDirectionInput;

parameterDbType = dbType;

parameterValue = value;

return parameter;

}

return null;

}

}

批量数据进入数据库使用addBatch()和executeBatch()方法

PreparedStatementaddBatch(); PreparedStatementexecuteBatch();需要注意的是一次最多不要超过50条:1因为插入的时候数据库已经锁定,然而若是一次性插入太多会造成其他业务的等待。2会造成内存的溢出

举例:PreparedStatement pst = (PreparedStatement) conprepareStatement("insert into values (,'')"); for (int i = 0; i < 10000; i++) { pstsetInt(1, i); // 把一个SQL命令加入命令列表 pstaddBatch(); } // 执行批量更新 pstexecuteBatch(); // 语句执行完毕,提交本事务 concommit();

因为数据库的限制,所以只能一次插入一条数据,多条的都是通过循环去完成的,DataAdapter所做的一次多条更新插入其实也是通过记录rowstate的状态去循环完成的,而且局限性很大,效率也不高,一般都不会用的,目前最快的应该是开启事务,循环插入,最后再一起提交是效率最高的。

<%

textarea=Request("textarea")'获取输入框的内容

If inStr(textarea,chr(13)&chr(10))>0 then'判断是否有换行符

textarea=Split(textarea,chr(13)&chr(10), -1, 1)'用换行符把内容分割成数组

For i=0 to UBound(textarea)'循环数组

ConnExecute "Insert Into [表名] (username,shuju,password) Values ('username值','"&textarea(i)&"','password值')" '写入数据库

Next

End If

%>

以上就是关于symfony2中有没有办法实现批量添加数据到数据库表中全部的内容,包括:symfony2中有没有办法实现批量添加数据到数据库表中、c#实现几种数据库的大数据批量插入、preparedstatement 怎么插入批量数据库等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9534867.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存