How do you read data from an Excel.xslx that is linked to Oracle? I can read the entire sheet just fine using C# and print to the console window, however this data that is being pulled (and refreshed every so often) cannot be read as a named range or table. I have tested reading data as named ranges/tables in other workbooks (not being pulled from Oracle) just fine. I would prefer not to read the entire sheet. So my question is how i would refer to this linked data as a named range or table in my sql query using C#, or if there is some other way to just read that linked data from Excel? Code is posted below followed by the output error (which has no build warnings/errors), 'PersonTable' is the named range i gave to the data that is being pulled from oracle11g.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
namespace ReadExcelNamedRage
{
class Program
{
static void Main(string[] args)
{
String connectionString = "Provider=Microsoft.Ace.OleDb.12.0; data source=c:\\documents and settings\\jhamandi\\desktop\\hrOracleTest.xlsx;extended properties=Excel 8.0";
//Select using a Named Range
string selectString = "SELECT * FROM PersonTable";
//Select using a Worksheet name
// string selectString = "SELECT * FROM [Sheet1$]";
OleDbConnection con = new OleDbConnection(connectionString);
OleDbCommand cmd = new OleDbCommand(selectString, con);
try
{
con.Open();
Console.WriteLine("Connection opened");
OleDbDataReader theData = cmd.ExecuteReader();
while (theData.Read())
{
Console.WriteLine("{0}: {1} ({2}) - {3} ({4})", theData.GetDouble(0),
theData.GetString(1), theData.GetString(2), theData.GetString(3), theData.GetString(4));
// Console.WriteLine("Writing");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
con.Dispose();
Console.WriteLine("Connection closed");
}
}
}
}
Connection opened
The Microsoft Access database engine could not find the object PersonTable. Ma
ke sure the object exists and that you spell its name and the path name correctl
y. If PersonTable is not a local object, check your network connection or cont
act the server administrator.
Connection closed
Press any key to continue . . .
Related
I'm trying to read a CSV file into a table that I have created in Visual Studio. I want to validate the values in the file to see if they are correct, if all the values pass the checks, it will go into the table. If any values are not correct, an error report will be created using a JSON file.
I have already got some test data ready but I'm not sure how to separate the correct data from the incorrect data after the checker are complete.
public partial class NHSBatchChecker : Form
{
public NHSBatchChecker()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = #"C:\Users\wy6282\Desktop\VS\NHSBATCHCHECKER\Test.txt"; // Start in C: drive
openFileDialog1.Title = "Browse Text Files";
openFileDialog1.RestoreDirectory = true;
openFileDialog1.DefaultExt = "txt"; // Extension of file is txt only
openFileDialog1.Filter = "Text|*.txt||*.*"; //Only text files allowed
openFileDialog1.CheckFileExists = true; // Error message if file does not exist
openFileDialog1.CheckPathExists = true; // Error message if invalid file path
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string connectionstring;
SqlConnection cnn;
connectionstring = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\wy6282\Desktop\VS\NHSBATCHCHECKER\nhsBatchChecker\Results.mdf;Integrated Security=True";
cnn = new SqlConnection(connectionstring);
cnn.Open();
SqlCommand command;
SqlDataAdapter adaper = new SqlDataAdapter();
string sql = "";
sql = "Insert into Results(NHS Number, Date of Birth, First Name, Last Name, Title, Gender) values()";
command = new SqlCommand(sql, cnn);
adaper.InsertCommand = new SqlCommand(sql, cnn);
adaper.InsertCommand.ExecuteNonQuery();
command.Dispose();
cnn.Close();
How do I add my valid records into the sql table?
you're trying to do too much in one go.
rule number 1: always split your problem into manageable junks:
read data from CSV.
filter incorrect data
save filtered data to database.
Now you have 3 distinct pieces of work to focus on.
Reading data from a CSV is trivial, there are many libraries that can help with that. Do a bit of research and pick one.
Create a class which holds the properties you need for validation checks and also those you want saved in the database.
Your goal is to create a list of these objects, one per row in csv. Of course, you may not be able to read everything in one go depending on how much data your csv holds, but you can pick a library which can deal with whatever size you have.
Now you have a list of objects. Write an algorithm which determines what is valid and what not, based on the rules you need. Your goal here is to end up with a possibly smaller list of the same objects, chucking out the invalid ones.
Save whatever is left in the database.
You need to start thinking about how you organize you code, don't just throw everything into the Click event of a button. You can create a model class to hold your objects, maybe create a separate class library where you can put your csv reading method.
Another class library perhaps for your filtering algorithm(s).
Your Click event should be fairly slim and only call library methods when it needs to do something. This is separation of concerns or SOC, which is a Solid Principle.
I am not sure how you plan to validate the datapoints, but the code below shows how to pull data from a CSV and load it into a SQL Server table.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Configuration;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string server = "EXCEL-PC\\EXCELDEVELOPER";
string database = "AdventureWorksLT2012";
string SQLServerConnectionString = String.Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI", server, database);
string CSVpath = #"C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Bulk Copy from CSV to SQL Server Table\WindowsFormsApplication1\bin"; // CSV file Path
string CSVFileConnectionString = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};;Extended Properties=\"text;HDR=Yes;FMT=Delimited\";", CSVpath);
var AllFiles = new DirectoryInfo(CSVpath).GetFiles("*.CSV");
string File_Name = string.Empty;
foreach (var file in AllFiles)
{
try
{
DataTable dt = new DataTable();
using (OleDbConnection con = new OleDbConnection(CSVFileConnectionString))
{
con.Open();
var csvQuery = string.Format("select * from [{0}]", file.Name);
using (OleDbDataAdapter da = new OleDbDataAdapter(csvQuery, con))
{
da.Fill(dt);
}
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(SQLServerConnectionString))
{
bulkCopy.ColumnMappings.Add(0, "MyGroup");
bulkCopy.ColumnMappings.Add(1, "ID");
bulkCopy.ColumnMappings.Add(2, "Name");
bulkCopy.ColumnMappings.Add(3, "Address");
bulkCopy.ColumnMappings.Add(4, "Country");
bulkCopy.DestinationTableName = "AllEmployees";
bulkCopy.BatchSize = 0;
bulkCopy.WriteToServer(dt);
bulkCopy.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
}
}
I'm trying to make a connection to a DB2 Database sitting on our AS400 (ISeries). I can connect to is successfully using the connection string but once I try to access the Tables I get this error: CPF9812: File SELECT in library *LIBL not found.
At this point I'm just trying to see if i can access the data in the table GLPCT.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
namespace Testing_Connection_to_GLDBFA
{
class Program
{
static void Main(string[] args)
{
string connectionstring = "Provider=IBMDARLA.DataSource.1;Data Source=INFINIUM;Persist Security Info=True;Password=MyPassword;User ID=UserID;Initial Catalog=S06947A4;Default Collection=GLDBFA";
string querySTring = "";
DataTable schema;
int i = 0;
using( OleDbConnection cn = new OleDbConnection(connectionstring))
{
querySTring = "SELECT * FROM GLPCT";
OleDbCommand command = new OleDbCommand(querySTring, cn);
cn.Open();
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader[0].ToString());
i++;
if (i == 20)
break;
}
cn.Close();
}
}
}
}
Any help or guidance is greatly appreciated.
Thanks in advance.
I'd expect to see the following error:
CPF9812: File GLPCT in library USERID not found.
As by default when using SQL naming the system will implicitly qualify unqualified table names with the user ID. For details, see here
It appears you are using an OLE DB provider instead of the .NET provider
If you want to use the library list, you'll need use system naming and ensure that the library list is configured on the connection.
For the OLEDB providers, you want to set the Library List and Naming Convention
<connection>.Open('Provider=IBMDA400;Data Source=SystemA;Library List=lib1,lib2, *USRLIBL;Naming Convention=1', 'Userid', 'Password');
For .NET provider, it's LibraryList and Naming properties.
Lastly, if you want to stay with the OLE DB provider, you might consider using the IBMDASQL instead of the IBMDARLA one.
Hi all Oracle experts,
I have a rather strange behaviour of a very very simple program only intended to test basic data acquisition from a remote Oracle database with C#.
I have created a simple C# program as follows:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Oracle.ManagedDataAccess.Client;
class Program
{
static void Main(string[] args)
{
var connectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP) (HOST={{Server}})(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME={{DataSource}})));User Id={{Username}};Password={{Password}};";
connectionString = connectionString.Replace("{{DataSource}}", "Actual service name");
connectionString = connectionString.Replace("{{Server}}", "Actual Server IP");
connectionString = connectionString.Replace("{{Username}}", "Actual username");
connectionString = connectionString.Replace("{{Password}}", "Actual password");
using (connection = new OracleConnection {ConnectionString = connectionString})
{
connection.Open();
using ( var cmd = connection.CreateCommand() )
{
cmd.CommandText = "SELECT * FROM Table";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
i++;
}
}
}
}
}
}
The table I am reading from has 220.000 entries, and the problem with the code is, that after an amount of "rows" the reader.Read() just stops. It is supposed to return "false" if there are no more records, and there are still records to come, but the Read() function is called and never returns. Even after letting it try for hours it does not come back.
Does anyone have had a similar experience?
I already heard not to use the Microsoft Oracle Data Driver, so I am using the one from oracle. But still the problem does not go away.
The amount of rows retrieved changes if you change the SQL Command, but also not in a very understandable way: I thought if this has to do with the network buffers I can reduce the columns to get more rows, but it works in the opposite direction. More columns result in more rows.
Any help is deeply appreciated.
I'm a real noob in .NET and i'm trying to link a simple command line application (in C#) with a SQL server database. I'm now able to connect the program with the database but not to recover the data that are in it. Here is my code :
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
string queryString = "SELECT USER_ID FROM dbo.ISALLOCATEDTO;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = queryString;
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
int i = 0;
while (reader.Read())
{
i++;
Console.WriteLine("Field "+i);
Console.WriteLine("\t{0}",reader[0]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
//Console.WriteLine("Hello world");
string x = Console.ReadLine();
}
static private string GetConnectionString()
{
return "Data Source=FR401388\\SQLEXPRESS;Initial Catalog=Test;";
+ "Integrated Security=SSPI";
}
}
}
But when i'm running it and even if my table is not empty (I've seen it in the sql server studio), I cannot recover the data by using the read() method.
What I've done so far : try to change the name of the datatable with a fake one : the datatable is not found (so the link between sql server database and programm seems to be valid).
I'm using Windows Authentication in sql server, dunno if it's changing anything... (Once again : i'm very new to all of that).
Thanks !
Your code should work.
A possible cause is: You are looking at a different database.
This is quite common if you use Server Explorer inside VS with a connectionstring different from the one used in code.
I am working on writing a simple program to import an excel sheet into my database but I am running into an error of:
Could not find installable ISAM
I am not sure what this means and after hours of searching with so many different topics I have turned to SO. There is a lot of talk of Jet and ACE where I am not sure what the difference is but here is the rundown: I have an excel file called test or test1 and I just want to import the first sheet in the file. here is my source code so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data.Common;
using System.Data.SqlClient;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
string filePath = null;
public Form1()
{
InitializeComponent();
}
//Method to check database connection
private void button1_Click(object sender, EventArgs e)
{
string connetionString = null;
SqlConnection cnn;
connetionString = "Data Source=Zach-PC;Initial Catalog=master;Integrated Security=SSPI;";
cnn = new SqlConnection(connetionString);
try
{
cnn.Open();
MessageBox.Show("Connection Open ! ");
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection ! ");
}
}
//Method to select a file
private void button2_Click(object sender, EventArgs e)
{
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/Users/Zach/Documents/test1.xls;Extended Properties=Excel 12.0,HDR=Yes;IMEX=1";
// Create Connection to Excel Workbook
using (OleDbConnection connection =
new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand
("Select * FROM [Sheet1$]", connection);
connection.Open(); //HERE IS WHERE THE ERROR IS
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=Zach-PC;Initial Catalog=master;Integrated Security=True";
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "Table";
bulkCopy.WriteToServer(dr);
MessageBox.Show("Data Exoprted To Sql Server Succefully");
}
}
}
}
}
}
Am I approaching this in the right manor?
You need to wrap Extended Properties part of the connection string in the quotation marks:
// here and here
// --> v v
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/Users/Zach/Documents/test1.xls;Extended Properties=""Excel 12.0,HDR=Yes;IMEX=1""";
The Office oledb driver is probably not installed on your computer. You should download it from microsoft website. After the installation, your code should run.
If you are reading office 2007 (or newer) excel files then I will suggest to use Open source library Epplus to read the excel file.It is purely .NET library and you wont be dependent on oledb driver.
epplus
EPPlus is a .net library that reads and writes Excel 2007/2010 files using the Open Office Xml format (xlsx).
you can easily read an excel file into datatable using this library. have a look at this thread
How convert stream excel file to datatable C#?