![](/img/trans.png)
[英]Insert text file data into SQL Server database table of specific column
[英]How to insert a data table into SQL Server database table?
我从一些Excel文件导入的数据和我有它保存到一个datatable
。 现在,我想将此信息保存在我的SQL Server
数据库中。
我在网上看到了很多信息,但我听不懂:
OLE
还是SQL Server
对象(例如dataAdapter
或connection
)? 我需要从他的Excel文件中读取员工每周工作时间报告,并将其保存到保存所有报告的数据库表中(每周用新记录更新数据库)。
Excel文件仅包含当前一周的报告。
在数据库中创建一个User-Defined TableType
:
CREATE TYPE [dbo].[MyTableType] AS TABLE(
[Id] int NOT NULL,
[Name] [nvarchar](128) NULL
)
并在您的Stored Procedure
定义一个参数:
CREATE PROCEDURE [dbo].[InsertTable]
@myTableType MyTableType readonly
AS
BEGIN
insert into [dbo].Records select * from @myTableType
END
并将您的DataTable
直接发送到sql server:
using (var command = new SqlCommand("InsertTable") {CommandType = CommandType.StoredProcedure})
{
var dt = new DataTable(); //create your own data table
command.Parameters.Add(new SqlParameter("@myTableType", dt));
SqlHelper.Exec(command);
}
要编辑存储过程中的值,可以声明具有相同类型的局部变量,然后将输入表插入其中:
DECLARE @modifiableTableType MyTableType
INSERT INTO @modifiableTableType SELECT * FROM @myTableType
然后,您可以编辑@modifiableTableType
:
UPDATE @modifiableTableType SET [Name] = 'new value'
如果这是您第一次保存数据表
执行此操作(使用批量复制)。 确保没有PK / FK约束
SqlBulkCopy bulkcopy = new SqlBulkCopy(myConnection);
//I assume you have created the table previously
//Someone else here already showed how
bulkcopy.DestinationTableName = table.TableName;
try
{
bulkcopy.WriteToServer(table);
}
catch(Exception e)
{
messagebox.show(e.message);
}
现在,既然您已经有了基本记录。 您只想检查现有记录中的新记录。 您可以简单地做到这一点。
这基本上将从数据库中获取现有表
DataTable Table = new DataTable();
SqlConnection Connection = new SqlConnection("ConnectionString");
//I assume you know better what is your connection string
SqlDataAdapter adapter = new SqlDataAdapter("Select * from " + TableName, Connection);
adapter.Fill(Table);
然后将此表传递给此函数
public DataTable CompareDataTables(DataTable first, DataTable second)
{
first.TableName = "FirstTable";
second.TableName = "SecondTable";
DataTable table = new DataTable("Difference");
try
{
using (DataSet ds = new DataSet())
{
ds.Tables.AddRange(new DataTable[] { first.Copy(), second.Copy() });
DataColumn[] firstcolumns = new DataColumn[ds.Tables[0].Columns.Count];
for (int i = 0; i < firstcolumns.Length; i++)
{
firstcolumns[i] = ds.Tables[0].Columns[i];
}
DataColumn[] secondcolumns = new DataColumn[ds.Table[1].Columns.Count];
for (int i = 0; i < secondcolumns.Length; i++)
{
secondcolumns[i] = ds.Tables[1].Columns[i];
}
DataRelation r = new DataRelation(string.Empty, firstcolumns, secondcolumns, false);
ds.Relations.Add(r);
for (int i = 0; i < first.Columns.Count; i++)
{
table.Columns.Add(first.Columns[i].ColumnName, first.Columns[i].DataType);
}
table.BeginLoadData();
foreach (DataRow parentrow in ds.Tables[0].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r);
if (childrows == null || childrows.Length == 0)
table.LoadDataRow(parentrow.ItemArray, true);
}
table.EndLoadData();
}
}
catch (Exception ex)
{
throw ex;
}
return table;
}
这将返回一个新的DataTable,其中已更改的行已更新。 请确保您正确调用该函数。 DataTable首先应该是最新的。
然后,使用此新的数据表再次重复批量复制功能。
我给出了一个非常简单的代码,我在解决方案中使用了该代码(我的问题陈述与您的相同)
SqlConnection con = connection string ;
//new SqlConnection("Data Source=.;uid=sa;pwd=sa123;database=Example1");
con.Open();
string sql = "Create Table abcd (";
foreach (DataColumn column in dt.Columns)
{
sql += "[" + column.ColumnName + "] " + "nvarchar(50)" + ",";
}
sql = sql.TrimEnd(new char[] { ',' }) + ")";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
using (var adapter = new SqlDataAdapter("SELECT * FROM abcd", con))
using(var builder = new SqlCommandBuilder(adapter))
{
adapter.InsertCommand = builder.GetInsertCommand();
adapter.Update(dt);
// adapter.Update(ds.Tables[0]); (Incase u have a data-set)
}
con.Close();
我给定了一个预定义的表名“ abcd”(您必须注意数据库中不存在使用该名称的表)。 如果适合您,请投票给我!!! :)
我建议您按照本文的建议进行批量插入: 使用C#DataTable和SQL Server OpenXML函数批量插入数据
我发现如果表具有主键,最好逐行添加到表中。 一次插入整个表会在自动增量上产生冲突。
这是我存储的Proc
CREATE PROCEDURE dbo.usp_InsertRowsIntoTable
@Year int,
@TeamName nvarchar(50),
AS
INSERT INTO [dbo.TeamOverview]
(Year,TeamName)
VALUES (@Year, @TeamName);
RETURN
我将此代码放入需要添加到表中的每一行的循环中:
insertRowbyRowIntoTable(Convert.ToInt16(ddlChooseYear.SelectedValue), name);
这是我的数据访问层代码:
public void insertRowbyRowIntoTable(int ddlValue, string name)
{
SqlConnection cnTemp = null;
string spName = null;
SqlCommand sqlCmdInsert = null;
try
{
cnTemp = helper.GetConnection();
using (SqlConnection connection = cnTemp)
{
if (cnTemp.State != ConnectionState.Open)
cnTemp.Open();
using (sqlCmdInsert = new SqlCommand(spName, cnTemp))
{
spName = "dbo.usp_InsertRowsIntoOverview";
sqlCmdInsert = new SqlCommand(spName, cnTemp);
sqlCmdInsert.CommandType = CommandType.StoredProcedure;
sqlCmdInsert.Parameters.AddWithValue("@Year", ddlValue);
sqlCmdInsert.Parameters.AddWithValue("@TeamName", name);
sqlCmdInsert.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (sqlCmdInsert != null)
sqlCmdInsert.Dispose();
if (cnTemp.State == ConnectionState.Open)
cnTemp.Close();
}
}
//best way to deal with this is sqlbulkcopy
//but if you dont like it you can do it like this
//read current sql table in an adapter
//add rows of datatable , I have mentioned a simple way of it
//and finally updating changes
Dim cnn As New SqlConnection("connection string")
cnn.Open()
Dim cmd As New SqlCommand("select * from sql_server_table", cnn)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
da.Fill(ds, "sql_server_table")
Dim cb As New SqlCommandBuilder(da)
//for each datatable row
ds.Tables("sql_server_table").Rows.Add(COl1, COl2)
da.Update(ds, "sql_server_table")
public bool BulkCopy(ExcelToSqlBo objExcelToSqlBo, DataTable dt, SqlConnection conn, SqlTransaction tx)
{
int check = 0;
bool result = false;
string getInsert = "";
try
{
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
if (dr != null)
{
if (check == 0)
{
getInsert = "INSERT INTO [tblTemp]([firstName],[lastName],[Father],[Mother],[Category]" +
",[sub_1],[sub_LG2])"+
" select '" + dr[0].ToString() + "','" + dr[1].ToString() + "','" + dr[2].ToString() + "','" + dr[3].ToString() + "','" + dr[4].ToString().Trim() + "','" + dr[5].ToString().Trim() + "','" + dr[6].ToString();
check += 1;
}
else
{
getInsert += " UNION ALL ";
getInsert += " select '" + dr[0].ToString() + "','" + dr[1].ToString() + "','" + dr[2].ToString() + "','" + dr[3].ToString() + "','" + dr[4].ToString().Trim() + "','" + dr[5].ToString().Trim() + "','" + dr[6].ToString() ;
check++;
}
}
}
result = common.ExecuteNonQuery(getInsert, DatabasesName, conn, tx);
}
else
{
throw new Exception("No row for insertion");
}
dt.Dispose();
}
catch (Exception ex)
{
dt.Dispose();
throw new Exception("Please attach file in Proper format.");
}
return result;
}
从我对问题的理解来看,这可以使用一个相当简单的解决方案。无论如何,下面是我建议的方法,该方法将一个数据表放入数据库中,然后使用SQL语句插入数据库中的表中。请注意我的解决方案正在使用MySQLConnection和MySqlCommand替换为SqlConnection和SqlCommand。
public void InsertTableIntoDB_CreditLimitSimple(System.Data.DataTable tblFormat)
{
for (int i = 0; i < tblFormat.Rows.Count; i++)
{
String InsertQuery = string.Empty;
InsertQuery = "INSERT INTO customercredit " +
"(ACCOUNT_CODE,NAME,CURRENCY,CREDIT_LIMIT) " +
"VALUES ('" + tblFormat.Rows[i]["AccountCode"].ToString() + "','" + tblFormat.Rows[i]["Name"].ToString() + "','" + tblFormat.Rows[i]["Currency"].ToString() + "','" + tblFormat.Rows[i]["CreditLimit"].ToString() + "')";
using (MySqlConnection destinationConnection = new MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
using (var dbcm = new MySqlCommand(InsertQuery, destinationConnection))
{
destinationConnection.Open();
dbcm.ExecuteNonQuery();
}
}
}//CreditLimit
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.