问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

SQLServer数据批量导入的几种方式

发布网友 发布时间:2023-07-31 06:25

我来回答

1个回答

热心网友 时间:2023-07-31 08:52



SQLServer数据批量导入的几种方式
说到SQLServer 的数据批量导入,下面用常用的几种方式做下对比,后面详细介绍每种方式如何使用(本文的代码使用语言c#)

导入方式
是否需写代码
导入过程能否对数据加工
插入数据的速度
多表数据导入
是否必需写SQL语句
1.通过SQLServer客户端管理工具
F
F

F
F
2.循环调用插入语句、或存储过程
T
T

T
T
3.使用SqlBulkCopy
T
F

F
F
4.使用SQLServer表值参数
T
T

T
T
1.通过SQLServer客户端管理工具
打开SQLServer客户端连接要操作的数据库引擎

右键要操作的数据库,选择任务--导入数据,第一次使用会弹出向导页如下图:



点下一步,一般要导入的数据都是excel,数据源我们选择Microsofy Excel(不同版本会有些差异),

浏览选择要导入的excel文件;

下一步选择目标数据源选择我们的SQLServer



根据需要一直点下一步,需要注意在选择表和数据源页面,根据实际需要选择对应的表,以及编辑列的映射,
最后点击完成,导入数据。

2.循环调用插入语句、或存储过程
此方法就是调用写好的sql语句或存储过程来循环的插入数据导数据库;根据需要可以在读取文件数据后,对数据进行校验和加工。

下面代码是一个循环插入的实现,如果需要输出导入进度可以用BackgroundWorker+ progressBar在页面上显示导入进度;

private int DataImport()
{
if (File.Exists(path))
File.Delete(path);
int i = 0;
// 打开数据库连接
string strConn = System.Configuration.ConfigurationManager.AppSettings["SsConnString"];
SqlConnection Coon = new SqlConnection(strConn);
if (Coon.State.Equals(ConnectionState.Closed))
{
Coon.Open();
}
foreach (DataRow dr in m_dt.Rows)
{
i++;
if (bkWorker.CancellationPending)
{
e.Cancel = true;
return -1;
}
SqlParameter[] parms = {
new SqlParameter("@Name", SqlDbType.VarChar, 32),
new SqlParameter("@Sheng", SqlDbType.VarChar),
new SqlParameter("@City", SqlDbType.VarChar),
new SqlParameter("@Xian", SqlDbType.VarChar)
};
try
{
parms[0].Value = (dr["姓名"] + "").Trim();
parms[7].Value = dr["省"] + "";
parms[8].Value = dr["市"] + "";
parms[9].Value = dr["县"] + "";
}
catch (Exception)
{
MessageBox.Show("确保数据表中的列名和模版中的一致!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return -1;
}
try
{
SqlCommand Cmd = Tools.CreateCmd("P_Data_Import", parms, Conn);
int iRet = Cmd.ExecuteNonQuery();
if (iRet == 0)
{
continue;
}
}
catch (Exception ex)
{
Tools.Log_Write("第" + (m_dt.Rows.IndexOf(dr)+1).ToString() + "行导入出错:" + ex.Message, "d:\\数据导入日志.txt");
continue;
}
}
if (MessageBox.Show("数据导入完成!,打开导入日志!", "提示") == DialogResult.OK)
{
this.buttonImport.Enabled = true;
if (File.Exists(path))
System.Diagnostics.Process.Start(path);
}
Conn.Close();
return -1;
}
// 打开数据库连接
public static SqlConnection ReturnConn()
{
string strConn = "server=数据库地址;uid=数据库账号;pwd=密码;database=数据库名"
SqlConnection Coon = new SqlConnection(strConn);
if (Coon.State.Equals(ConnectionState.Closed))
{
Coon.Open();
}
return Coon;
}
// 执行带参数的存储过程
public static SqlCommand CreateCmd(string procName, SqlParameter[] prams, SqlConnection Conn)
{
SqlConnection SqlConn = Conn;
if (SqlConn.State.Equals(ConnectionState.Closed))
{
SqlConn.Open();
}
SqlCommand Cmd = new SqlCommand();
Cmd.CommandType = CommandType.StoredProcere;
Cmd.Connection = SqlConn;
Cmd.CommandText = procName;
if (prams != null)
{
foreach (SqlParameter parameter in prams)
{
if (parameter != null)
{
Cmd.Parameters.Add(parameter);
}
}
}
return Cmd;
}
3.使用SqlBulkCopy
下面以导入学生消课数据为例,导入数据的方法,关于SqlBulkCopy(官方解释:允许你使用其他源的数据有效地批量加载 SQL Server 表。)的使用可以到到网上搜索,资料一大堆,官方文档直通通车

首先要构造要导入数据格式的DataTable类型的对象(TransferData)、其次要设置和数据源的列映射关系

Stopwatch 用于计算导入数据耗费时间

private void InsertTwo()
{
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() != DialogResult.OK)
{
return;
}
Stopwatch sw = new Stopwatch();
//给datatable 构造Column
DataTable dt = Tools.TransferData(fd.FileName, "sheet1","");
dt.Columns.Add(xhFee);
this.btn_Import.Enabled = false;
string strConn = System.Configuration.ConfigurationManager.AppSettings["SsConnString"];
using (SqlConnection conn = new SqlConnection(strConn))
{
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn);
bulkCopy.DestinationTableName = "T_FI_IncomeDetail";
bulkCopy.BatchSize = dt.Rows.Count;
//设置列对应关系
bulkCopy.ColumnMappings.Add("辅导类型", "FdId");
bulkCopy.ColumnMappings.Add("消耗课时或课次", "XhKeshi");
bulkCopy.ColumnMappings.Add("消耗日期", "CreateTime");
bulkCopy.ColumnMappings.Add("学生姓名", "Name");
conn.Open();
sw.Start();
int totalRow = dt.Rows.Count;
if (dt != null && dt.Rows.Count != 0)
{
dateTimeDelete.Value = Convert.ToDateTime(dt.Rows[0]["消耗日期"]);
bulkCopy.WriteToServer(dt);
sw.Stop();
}
MessageBox.Show(string.Format("插入{0}条记录共花费{1}毫秒", totalRow, sw.ElapsedMilliseconds));
}
}
// 获取excel数据并填充到DataTable
public static TransferData(string excelFile, string sheetName,string strScreen)
{
System.Data.DataTable dt = new System.Data.DataTable();
try
{
//获取全部数据
string strConn = "Provider=Microsoft.Ace.Oledb.12.0;Data Source=" + excelFile + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1;'";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
OleDbDataAdapter myCommand = null;
myCommand = new OleDbDataAdapter("Select * from [Sheet1$] " + strScreen, strConn);
myCommand.Fill(dt);
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return dt;
}
4.使用SQLServer表值参数
该方法对于需要批量导入数据,有需要对数据进行逻辑操作,影响多张表时,尤其实用;本例以导入用户资料为例,亲测由于逻辑复杂在存储过程中使用游标处理2000条数据,2s就可完全导入。

主要是应用了SQLServer的表类型参数,通过给存储过程传入表数据,让sql操作都在数据库中进行,提升操作性能。

首先要根据要在数据库 创建自定义表类型,创建语句格式如下:

CREATE TYPE [dbo].[UserInfo] AS TABLE(
[Name] [varchar](32) NULL,
[Code] [varchar](32) NULL,
[Gender] [varchar](32) NULL,
[Birthday] [datetime] NULL
)
存储过程使用方式:UserInfo即为提前创建好的自定义表类型

create proc procName
(
@DataTable UserInfo readonly
)
as
begin
-- 实现自己的逻辑对@DataTable的使用可以向普通表一样,
-- 建议 如果需要对@DataTable需要连表过滤数据,请使用临时表, 否则可能会提示 超出数据库设置的最大查询时间
--(在数据库引擎,右键属性--连接中可以查看使用查询*器防止查询时间过长,不勾选默认30s),
-- 建议逻辑操作能放在代码中处理的,不要放在存储过程中,为了减小数据库服务器压力
end
代码调用实例:

private int DataImport1(object sender)
{
Stopwatch sw = new Stopwatch();
sw.Start();
string path = "d:\\数据导入日志.txt";
if (File.Exists(path))
File.Delete(path);
int count = m_dt.Rows.Count;
SqlConnection Conn = SsZongs.ReturnConn();
DataTable dt = new DataTable("userIfo");
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Code", typeof(string));
dt.Columns.Add("Gender", typeof(string));
dt.Columns.Add("Birthday", typeof(DateTime));
try
{
for (int i = 0; i < count; i++)
{
try
{
dt.Rows.Add((m_dt.Rows[i]["姓名"] + "").Trim(),
m_dt.Rows[i]["编号"].ToString(),
m_dt.Rows[i]["性别"].ToString(),
m_dt.Rows[i]["出生日期"]
);
}
catch (Exception)
{
MessageBox.Show("确保数据表中的列名和模版中的一致!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return -1;
}
}
Tools.insertTableToDB(dt, "procName");
}
catch (Exception ex)
{
Tools.Log_Write(ex.Message, "d:\\数据导入日志.txt");
}
finally
{
sw.Stop();
if (MessageBox.Show("数据导入完成!耗时"+ sw.ElapsedMilliseconds + "毫秒,打开导入日志!", "提示") == DialogResult.OK)
{
this.buttonImport.Enabled = true;
if (File.Exists(path))
System.Diagnostics.Process.Start(path);
}
}
return -1;
}
public static void insertTableToDB(System.Data.DataTable dt,string procName)
{
SqlConnection sqlCon = SsZongs.ReturnConn();
using (var cmd = new SqlCommand(procName, sqlCon))
{
cmd.CommandType = CommandType.StoredProcere;
var param = new SqlParameter("@DataTable", SqlDbType.Structured) { Value = dt };
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
sqlCon.Close();
}
总结
以上几种方式,我在实际工作中都有使用, 具体业务还需要根据情况选择合适的方案。

文档编写能力不好,有需要的可以随时交流。
我的掘金
SQLServer数据批量导入的几种方式
标签:elfuse数据库服务器blebatchtail图片ide资料

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
水笔在手上画画会不会被衣服搽掉下来 老人每天大便次数很多量不多也不稀,每天还会拉三四次水应经三个月了... 从大连飞机场怎么去大连经济开发区5彩城K区的大连金港大酒店 除了打 ... 请问从大连周水子国际机场到经济技术开发区怎么走最省钱? 中国古代名刀总录中国古代十大名刀 怎样把qq安装到iphone里面 苏科大什么梗 苏科大叫什么名字 lol苏科大是苏州科技大学的吗 lol苏州科技大学为什么这么厉害 优尔精医用降温贴是不是保健品? 江汉大学师范专业毕业后是教小学还是教初中啊? 江汉大学实验师范学院的学校简介 我脸上的痘痘越来越多怎么办,感觉像皮肤里起的很大的 预防宝宝肥胖,新手妈妈应该怎么做? 迅游世界的背景故事 为何到处是兽人笔趣 为何到处是兽人np 振华三部曲,多少人青春故事 请问苏州阳澄湖莲花岛怎么样? 何以笙箫默 怎么剧情一点也不好看呢? 何以笙箫默中有个地方一直不懂 为什么在赵默笙去过医院后以珅说若不... 禾健的玛卡片,一片多少克啊? 排气管排机油是咋回事 脚踏式水龙头特点是什么? 速热水龙头特点是什么 电热水龙头有什么特点 谁能批出晋城天地王坡煤矿的精煤?急急急 留下联系方式 非诚勿扰_百度... 天地科技何家塔煤矿项目部具体负责什么 天地王坡在哪??? 气自华前一句是什么意思 水培豆芽的步骤是 江苏省地震局公务员编制待遇 在地震局工作算公务员吗 地震局招聘进去的是公务员吗 亚麻籽微波炉加热时间 小麦种子微波炉加热热度可持续多久 初二历史社会:郭靖杨康两个人名字的出处? 史上真的有郭靖杨康的人物吗求大神帮助 历史上杨过的父亲 幼儿大便不成形喝酸奶有用吗? 附身记电子书txt全集下载 防损员 ?? 公安四防是哪四防 收音机,调频88.7里有一首歌,歌词里有you want sun sun sun sunshine 【羯羊】 QQ号怎么注销?QQ号注销方法 用QQ申请的把QQ注销了,别人申请去了,在能用我这个微信吗? 为什么养金丝熊费钱 约翰迪尔484工作两千小时排气管楼机油怎么办 迪尔5-754发动机排气管排机油是怎么回事?