string path = string.Concat(Server.MapPath("~/TempFiles/"), FileUpload1.FileName);
//Save File as Temp then you can delete it if you want
FileUpload1.SaveAs(path);
string excelConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", path);
// Create Connection to Excel Workbook
using (OleDbConnection connection =
new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand
("Select * FROM [Sheet1$]", connection);
connection.Open();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = #conn;
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName ="Table1";
bulkCopy.WriteToServer(dr);
Label1.Text = "The Client data has been exported successfully from Excel to SQL";
}
}
}
I am trying to import data from excel to SQL Server, it works fine till I am not passing date but now I want to pass the date to SQL Server it provides error as datatype not matches.
Anyone has logic or please suggest me what can I do to ..
Might be the column in the Excel Sheet is not in a valid date format.
Change it to Date Type.
Select the Column in the Excel Sheet -> Right Click -> Format Cells ->
Number Tab -> Select Date -> Choose your desired Type -> Ok
Then you try to Import...
The DateTime you read from excel is OLE Automation date and you have to convert it to c# DateTime before you insert in to sql server. It would be double value for date when you read from excel. You can use DateTime.FromOADate to convert the double value to DateTime. You can use SqlBulkCopy.WriteToServer(DataTable table), this method allows you to pass the datatable. You can change the date in datatable in require format and use it to save bulk data in sql server. You can import excel data to datatable, this article will help you.
DateTime dt = DateTime.FromOADate(double.Parse(stringVariableContainingDateTime));
It works i tried to convert it in datatble den change datatype and then insert
string sqlConnectionString = #conn;
command.CommandType = CommandType.Text;
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
DataSet objDataset1 = new DataSet();
objAdapter1.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
if (dt.Rows[0][5].ToString() != "")
{
DateTime dt1 = cf.texttodb(dt.Rows[0][5].ToString());
dt.Rows[i][5] = dt1;
}}
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "Tablename";
bulkCopy.WriteToServer(dt);
Label1.Text = "The Client data has been exported successfully from Excel to SQL";
}
in this i had created a function txtdob which converts my string to datetime format
Thank you
i tried it workes if u feel so mark it as answer
Related
I am reading excel data using the OleDbDataAdapter for doing this I am using the below code. My excel file has 80 rows and 19 columns. Each column represents different languages(e.g English Arabic, Chinese, etc).
Each row has certain strings.
public DataSet ReadExcelFile(string dataSource)
{
DataSet ds = new DataSet();
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + dataSource
+ " ; Extended Properties='Excel 12.0; IMEX=1'";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
// Get all Sheets in Excel File
DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
// Loop through all Sheets to get data
foreach (DataRow dr in dtSheet.Rows)
{
string sheetName = dr["TABLE_NAME"].ToString();
if (!sheetName.EndsWith("$"))
continue;
// Get all rows from the Sheet
cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
DataTable dt = new DataTable();
dt.TableName = sheetName;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dt);
ds.Tables.Add(dt);
}
cmd = null;
conn.Close();
}
return ds;
}
It works perfectly fine except for a few cells. for the few cells table does not have complete string this is happening for the Chinese language:
for example, my string is:
“个性化喂养模式”允许您预置常用的喂养模式。一旦设定好 , 当按“模式”键时 , 它将自动出现在喂养模式列表中。
-----------------------------------------------
您可以创建 , 编辑或删除个性化喂养模式。
-----------------------------------------------
提示 : 个性化喂养模式可能会被默认喂养列表隐藏。
-----------------------------------------------
使用“>”键选择需要的喂养模式。"
But I am getting only:
“个性化喂养模式”允许您预置常用的喂养模式。一旦设定好 , 当按“模式”键时 , 它将自动出现在喂养模式列表中。
-----------------------------------------------
您可以创建 , 编辑或删除个性化喂养模式。
-----------------------------------------------
提示 : 个性化喂养模式可能会被默认喂养列表隐藏。
-----------------------------------------------
The last row is missing.
This is happening only for 3 cell rest cell are coming properly.
It seems that it is being truncated to 255 characters.
According to this Microsoft Oledb truncates the data length to 255 characters
When you use OLEDB providers then the datatype is determined automatically by the provider based on the first 8 rows. If you have lengthy cells in the first 8 rows then data type will be set as text and otherwise it will be memo type which can hold 255 characters only. To overcome this issue either change the registry setting as mentioned in below KB article: http://support.microsoft.com/kb/281517 or use Microsoft.Jet.OLEDB provider to read the data.
Or you may try the OpenXml approach. Parse and read a large spreadsheet document (Open XML SDK)
i am trying to read excel data to C# using ODBC here is my code
string lstrFileName = "Sheet1";
//string strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq="+path+ ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
string strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=E:\\T1.xlsx;Extensions=xls/xlsx;Persist Security Info=False";
DataTable ds;
using (OdbcConnection oConn = new OdbcConnection(strConnString))
{
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
OdbcDataAdapter oAdap = new OdbcDataAdapter();
oAdap.SelectCommand = oCmd;
ds = new DataTable();
oAdap.Fill(ds);
oAdap.Dispose();
// ds.Dispose();
}
}
my sample data
A
1
2
3
AA
BB
its data table its read 1,2,3 and two blank row
i can understand because of first row its deciding data type , but how can i convert as String and read all row .
Any suggestion .
i Already tried CStr but no help .
For a previous discussion of similar problem here, please check following:
DBNull in non-empty cell when reading Excel file through OleDB
As a workaround, you may also format the column as "text"(i.e. in Excel, select column, right click "Format Cells..."), though this might be impractical if you will process large number of files or if you must not touch the file..
This is partially speculation, but when reading an Excel document as a database, the adapter has to make a judgement on datatypes and usually does a pretty good job. However, because Excel allows mixed datatypes (and databases do not), it occasionally gets it wrong.
My recommendation would to be to not use a data adapter, and just read in every field as an object type. From there, you can easily cast them to strings (StringBuilder, ToString(), etc) or even TryParse into fields you suspect they should be, ignoring the ODBC datatype.
Something like this would be a boilerplate for that:
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
using (OdbcDataReader reader = oCmd.ExecuteReader())
{
object[] fields = new object[reader.FieldCount];
while (reader.Read())
{
reader.GetValues(fields);
// do something with fields
}
}
}
I have a Foxpro .DBF file. I am using OLEDB driver to read the .DBF file. I can query the DBF and utilize its .CDX index file(cause it is automatically opened). My problem is that I want to query it with the .NDX index file (which is not automatically opened when the .DBF is opened). How can I open the .NDX file in C# using OLEDB driver cause the DBF is really big to search for a record without the index? Thanks all! Here is the code I am using to read the DBF.
OleDbConnection oleDbConnection = null;
try
{
DataTable resultTable = new DataTable();
using (oleDbConnection = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\DSPC-1.DBF;Exclusive=No"))
{
oleDbConnection.Open();
if (oleDbConnection.State == ConnectionState.Open)
{
OleDbDataAdapter dataApdapter = new OleDbDataAdapter();
OleDbCommand command = oleDbConnection.CreateCommand();
string selectCmd = #"select * from P:\Test\DSPC-1 where dp_file = '860003'";
command.CommandType = CommandType.Text;
command.CommandText = selectCmd;
dataApdapter.SelectCommand = command;
dataApdapter.Fill(resultTable);
foreach(DataRow row in resultTable.Rows)
{
//Write the data of each record
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
try
{
oleDbConnection.Close();
}
catch (Exception e)
{
Console.WriteLine("Failed to close Oledb connection: " + e.Message);
}
}
ndx files wouldn't be opened by default and those are a thing of the past really, why wouldn't you simply add your index to your CDX. If it is not an option, then ExecScript suggestion by DRapp is what you can do. He was very close. Here is how you could do that:
string myCommand = #"Use ('P:\Test\DSPC-1') alias myData
Set Index To ('P:\Test\DSPC-1_Custom.NDX')
select * from myData ;
where dp_file = '860003' ;
into cursor crsResult ;
nofilter
SetResultset('crsResult')";
DataTable resultTable = new DataTable();
using (oleDbConnection = new OleDbConnection(#"Provider=VFPOLEDB;Data Source=P:\Test"))
{
oleDbConnection.Open();
OleDbCommand command = new OleDbCommand("ExecScript", oleDbConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("code", myCommand);
resultTable.Load(cmd.ExecuteReader());
oleDbConnection.Close();
}
Your connection string should only reference the PATH to where the .dbf files are located.
Then, your query is just by the table name.
new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\;Exclusive=No"))
selectCmd = #"select * from DSPC-1 where dp_file = '860003'";
As for using the .NDX, how / where was that created... Is that an old dBASE file you are using the Visual Foxpro driver for?
If it is a separate as described, you might need to do via an ExecScript() to explicitly open the file first WITH the index, THEN run your query. This is just a SAMPLE WITH YOUR FIXED value. You would probably have to PARAMETERIZE it otherwise you would be open to sql-injection.
cmd.CommandText = string.Format(
#"EXECSCRIPT('
USE DSPC-1 INDEX YourDSPC-1.NDX
SELECT * from DSPC-1 where dp_file = '860003'" );
Also, you might have issue with your table names being hyphenated, you may need to wrap it in [square-brackets], but not positive if it is an issue.
UPDATE: this happens with OdbcConnection but goes away with SqlConnection. Is there any way to read a "date" via OdbcConnection?
I have a Sql Server database table with a "date" and a "datetime" column. Whenever I use C# ODBC, it returns the Date column as a string. But I would rather it return the Date as a DateTime. Is there any way to make that happen?
string sql = "select dateColumn, dateTimeColumn from Test_Table";
string dsn = "Driver={SQL Server};Server={...};Database=...;Trusted_Connection=True;";
using (OdbcConnection conn = new OdbcConnection(ConfigManager.GetLoansDatabaseDSN()))
{
conn.Open();
OdbcCommand command = new OdbcCommand()
{
Connection = conn,
CommandText = sql
};
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
DataSet ds = new DataSet();
adapter.Fill(ds);
DataTable table = ds.Tables[0];
//The type of "dateColumn" is now string not DateTime
}
}
One of two ways.
Cast your dateColumn to a DateTime
string sql = "select Convert(DateTime, dateColumn) as dateColumn, dateTimeColumn from Test_Table";
Build your DataTable manually to include the columns type.
I'm importing data in a SQL Server 2008 database from excel file where the first row is headers (HDR=1). The thing is that the second row is also kind of headers which i don't really need to be imported. So how do I ignore the second row from that excel (I guess if the first row is the headers, the actual second row in excel is first)?
In MySQL is just about saying IGNORE LINES 1 in the end of import command ... How do I do it in SQL Server?
Here is part of the code doing that:
//Create Connection to Excel work book
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select [task_code],[status_code],[wbs] from [task$]", excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(connectionString);
//Give your Destination table name
sqlBulk.DestinationTableName = "task";
sqlBulk.WriteToServer(dReader);
sqlBulk.Close();
Thanks
Use the following:
...
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
if( !dReader.Read() || !dReader.Read())
return "No data";
SqlBulkCopy sqlBulk = new SqlBulkCopy(connectionString);
...
A quick solution would be to:
Copy the file
Use Office interop to delete the second line of the spreadsheet
Import the amended spreadsheet
To delete the line from the spreadsheet:
public static void DeleteRow(string pathToFile, string sheetName, string cellRef)
{
Application app= new Application();
Workbook workbook = app.Workbooks.Open(pathToFile);
for (int sheetNum = 1; sheetNum < workbook.Sheets.Count + 1; sheetNum++)
{
Worksheet sheet = (Worksheet)workbook.Sheets[sheetNum];
if (sheet.Name != sheetName)
{
continue;
}
Range secondRow = sheet.Range[cellRef];
secondRow.EntireRow.Delete();
}
workbook.Save();
workbook.Close();
app.Quit();
}