Excel文件到TEMP SQL Server数据库表,包含未知列



我有一个Excel文件,它有4个已知的列标题,其余的将是年/月。每个文件中的"年/月"列标题可以不同。可以有任意数量的Y/M列。在我的WinForms应用程序中,用户将选择一个Excel文件。我需要弄清楚的是如何获取Excel文件,将其导入数据库中的临时表,做一些事情,然后删除临时表。我所看到的一切都是你提前知道专栏的内容。

我怎样才能做到这一点?这可能吗?

我会尽量说得更清楚。我有一个excel文件。列的数量和名称会有所不同(所以我不能只创建一个临时表,因为我不知道字段是什么(。我将excel文件放入我的应用程序中的本地数据表中。我需要在我的sql数据库上创建一个表来镜像本地数据库,然后将数据复制到那里。因此,从我的应用程序来看,我如何在mssql服务器上创建一个临时表。

(注释变得相当混乱。这是我从excel文件中获取表格的一个例程-C#抱歉(:

private List<System.Data.DataTable> GetTablesFromExcel(string dataSource)
{
List<System.Data.DataTable> tables = new List<System.Data.DataTable>();
using (OleDbConnection con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;"+
string.Format("Data Source={0};",dataSource)+
"Extended Properties="Excel 12.0;HDR=Yes""))
{
con.Open();
var schemaTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,null);
foreach (DataRow row in schemaTable.Rows)
{
string sheetName = (string)row["TABLE_NAME"];
OleDbCommand cmd = new OleDbCommand(string.Format("Select * from [{0}]",sheetName), con);
System.Data.DataTable t = new System.Data.DataTable(sheetName);
t.Load( cmd.ExecuteReader() );
tables.Add( t );
}
con.Close();
}
return tables;
}

编辑:这是SqlBulkCopy示例(很抱歉,注释也是土耳其语的,但你可以看到临时表的创建是用字符串完成的,因此你可以在运行时用StringBuilder构建(:

static readonly string sqlConnectionString = @"server=.SQLExpress;Trusted_Connection=yes;";
static readonly string path = @"d:tempdersler.xlsx"; // excel dosyasi
static readonly string sheetName = "Dersler$";
void Main()
{
using (OleDbConnection cn = new OleDbConnection(
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path +
";Extended Properties="Excel 12.0;HDR=Yes""))
using (SqlConnection scn = new SqlConnection(sqlConnectionString))
{
// Excelden veriyi al ve SqlBulkCopy ile servera yaz  
// Kaynak
OleDbCommand cmd = new OleDbCommand(String.Format("select * from [{0}]", sheetName), cn);

SqlBulkCopy sbc = new SqlBulkCopy(scn);
// Mapping  
sbc.ColumnMappings.Add(0, "[SiraNo]");
sbc.ColumnMappings.Add(1, "[DersinAdi]");
sbc.ColumnMappings.Add(2, "[SinifTuru]");
sbc.ColumnMappings.Add(3, "[SinifSeviyesi]");
sbc.ColumnMappings.Add(4, "[DersTuru]");
sbc.ColumnMappings.Add(5, "[Secmeli]");
cn.Open();
scn.Open();
SqlCommand createTemp = new SqlCommand();
createTemp.CommandText = @"if exists
(SELECT * FROM tempdb.sys.objects 
WHERE object_id = OBJECT_ID(N'[tempdb]..[##Dersler]','U'))
BEGIN
drop table [##Dersler];
END

create table ##Dersler 
(
[SiraNo] int primary key not null,
[DersinAdi] nvarchar(250) not null,
[SinifTuru] nvarchar(50) null,
[SinifSeviyesi] int,
[DersTuru] nvarchar(50),
[Secmeli] bit
)
";
createTemp.Connection = scn;
createTemp.ExecuteNonQuery();
OleDbDataReader rdr = cmd.ExecuteReader();

// SqlBulkCopy'nin propertyleri
sbc.DestinationTableName = "##Dersler";
sbc.NotifyAfter = 20; // 10000 alti kullanilmaz da sizin dataniz cok az
sbc.BatchSize = 10;
sbc.BulkCopyTimeout = 300; // Saniye. 5 dk cok bile fazla
sbc.EnableStreaming = true;
sbc.SqlRowsCopied += (sender, e) =>
{
Console.WriteLine("-- Copied {0} rows to {1}.",
e.RowsCopied,
((SqlBulkCopy)sender).DestinationTableName);
};
sbc.WriteToServer(rdr);
if (!rdr.IsClosed) { rdr.Close(); }
cn.Close();

DataTable t = new DataTable(); // Yazdigimiza bakalim
t.Load(new SqlCommand("select * from ##Dersler", scn).ExecuteReader());

scn.Close();
Form f = new Form();
DataGridView dgv = new DataGridView {Dock=DockStyle.Fill, DataSource=t};
f.Controls.Add(dgv);
f.Show();
}
}

最新更新