Sorry for the vague title but I'm not sure how best to word it.
Basically, the issue that I'm having is that I initially was using an oledbconnection in C# to initiate a connection to a spreadsheet, query it, and load the results into a .net datatable. Unfortunately, it maxes out at 255 fields which I have around 600.
So, what I did instead was I created a dataset and tried to load 4 separate data tables with separate queries. Now for some reason, what's crazy to me is, if I load lets say, the first data table with 190 fields, and then I go on to query the spreadsheet again, if I go over that 250 mark (which I'd have 60 left), I get the following error:
An exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll but was not handled in user code
Additional information: No value given for one or more required parameters.
If I reduce the amount of fields in the second table to equal less than 250 though, it works. Anyway, is there a way that I can somehow clear the cache of the oledbconnection to somehow drop the first 190 fields or whatever is holding the result of the excel query so I can move on to the next? I tried doing a data adapter dispose but that didn't work, same issue. If I do a connection.dispose, I have to re-initialize the connection anyway. Is there a way I can still do this without having to drop the connection? Code below:
OleDbConnection cnn = new OleDbConnection(Settings.ExcelCN);
OleDbCommand fillT1 = new OleDbCommand(Settings.Excel_Proj_Select_1, cnn);
OleDbCommand fillT2 = new OleDbCommand(Settings.Excel_Proj_Select_2, cnn);
OleDbCommand fillT3 = new OleDbCommand(Settings.Excel_Proj_Select_3, cnn);
OleDbCommand fillT4 = new OleDbCommand(Settings.Excel_Proj_Select_4, cnn);
OleDbCommand updateCnt = new OleDbCommand(Settings.Excel_Update_Count_Select, cnn);
cnn.Open();
OleDbDataAdapter adp1 = new OleDbDataAdapter(fillT1);
OleDbDataAdapter adp2 = new OleDbDataAdapter(fillT2);
OleDbDataAdapter adp3 = new OleDbDataAdapter(fillT3);
OleDbDataAdapter adp4 = new OleDbDataAdapter(fillT4);
DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
DataTable dt3 = new DataTable();
DataTable dt4 = new DataTable();
DataSet ds1 = new DataSet();
adp1.Fill(dt1);
ds1.Tables.Add(dt1);
adp2.Fill(dt2);
ds1.Tables.Add(dt2);
adp3.Fill(dt3);
ds1.Tables.Add(dt3);
adp4.Fill(dt4);
ds1.Tables.Add(dt4);
int rowcount = updateCnt.ExecuteNonQuery();
cnn.Close();
Related
I'm writing an API that will query a database given certain parameters. Some of those parameters will be supplied by the calling app (which should be trustworthy), but some of them will be supplied from user input.
If I were getting a small number of results I would normally use an OleDbCommand and use prepared statements via the Parameters field, as seen here
string sql = "Select * from [Table1] where Empid = ?";
OleDbCommand cmd = new OleDbCommand(sql, conn);
OleDbParameter tableParam = new OleDbParameter("#fieldvalue", value);
cmd.Parameters.Add(tableParam);
cmd.Prepare();
However, since I will be getting potentially many results (possibly the entire contents of a table), I want to use an OleDbDataAdapter to fill a DataTable to make handling and returning the data more convenient:
DataTable dt = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter(sql, connstring);
da.Fill(dt);
The problem is that I don't know how to use prepared statements with an OleDbDataAdapter. How do I do that, or is there another way to guarantee database security when using an OleDbDataAdapter?
The OleDbDataAdapter exposes the SelectCommand property (an OleDbCommand) built by the adapter with your query text. You can use it to 'prepare' the command used by the OleDbDataAdapter supplying the parameter required by the command text.
DataTable dt = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter(sql, connstring);
da.SelectCommand.Parameters.Add("#fieldvalue", OleDbType.Integer).Value = value;
da.Fill(dt);
I want to insert a row into the Database using SqlDataAdapter. I've 2 tables (Custormers & Orders) in CustomerOrders database and has more than thousand records. I want to create a GUI (TextBoxes) for adding new customer & orders into the Database to their respective tables.
How should I do it?
I guess the method that is usually followed is
dataAdapter = new SqlDataAdapter (sqlQuery, conn);
dataSet = new DataSet();
da.Fill(dataSet);
Now take the values from textboxes (or use DataBinding) to add a new row into the dataSet and call
da.Update(dataSet);
But the Question is Why should I fetch all other records into dataSet using da.Fill(dataSet ) in the first place? I just want to add a single new record.
For this purpose what I'm doing is, Creating the schema of the Database in the DataSet. like this:
DataSet customerOrders = new DataSet("CustomerOrders");
DataTable customers = customerOrders.Tables.Add("Customers");
DataTable orders = customerOrders.Tables.Add("Orders");
customers.Columns.Add("CustomerID", Type.GetType("System.Int32"));
customers.Columns.Add("FirstName", Type.GetType("System.String"));
customers.Columns.Add("LastName", Type.GetType("System.String"));
customers.Columns.Add("Phone", Type.GetType("System.String"));
customers.Columns.Add("Email", Type.GetType("System.String"));
orders.Columns.Add("CustomerID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderAmount", Type.GetType("System.Double"));
orders.Columns.Add("OrderDate", Type.GetType("System.DateTime"));
customerOrders.Relations.Add("Cust_Order_Rel", customerOrders.Tables["Customers"].Columns["CustomerID"], customerOrders.Tables["Orders"].Columns["CustomerID"]);
I used DataBinding to bind these columns to respective text boxes.
Now I'm confused! What should I do next? How to use Insert command? Because I didn't give any dataAdapter.SelectCommand so dataAdapter.Update() wont work I guess. Please suggest a correct approach.
Set the select command with a "0 = 1" filter and use an SqlCommandBuilder so that the insert command is automatically generated for you.
var sqlQuery = "select * from Customers where 0 = 1";
dataAdapter = new SqlDataAdapter(sqlQuery, conn);
dataSet = new DataSet();
dataAdapter.Fill(dataSet);
var newRow = dataSet.Tables["Customers"].NewRow();
newRow["CustomerID"] = 55;
dataSet.Tables["Customers"].Rows.Add(newRow);
new SqlCommandBuilder(dataAdapter);
dataAdapter.Update(dataSet);
You can fill the dataSet with an empty set e.g.:
da = new SqlDataAdapter ("SELECT * FROM Customers WHERE id = -1", conn);
dataSet = new DataSet();
da.Fill(dataSet);
Then you add your rows and call update.
For this scenario though it would probably be better not to use SqlDataAdapter. Instead use the SqlCommand object directly for insertion. (Even better, use LINQ to SQL or any other ORM)
SqlConnection con = new SqlConnection("Data Source=(local);Initial Catalog=test;Integrated Security=True");
SqlDataAdapter da=new SqlDataAdapter("Insert Into Employee values("+textBox1.Text+",'"+textBox2.Text+"','"+textBox3.Text+"',"+textBox4.Text+")",con);
DataSet ds = new DataSet();
da.Fill(ds);
I have to do first time. You can try it . It works well.
I'm currently trying to use C# to read through an SQL DB. To do so, I use OleDB with a select statement. This goes into a dataset, which then populates a data adapter. I then iterate through each row and calculate stuff.
First of all, I feel like there's a better/more efficient way of doing this because I NEVER actually write back to the SQL DB. I just calculate based on what I'm selecting.
Anyways, past a certain point I get out of memory errors and/or an error from Ssms.exe saying "a new guard page for the stack cannot be created."
From the other questions I've seen, I need to use DataReader but I can't seem to get it to work the same way as the data adapter (which I suppose isn't that surprising).
The code I have now:
OleDbConnection myConn = new OleDbConnection(#"SQLDB connection string here");
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = <selectstatement here>
cmd.Connection = myConn;
cmd.CommandTimeout = 0;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
myConn.Close();
foreach (DataTable table in ds.Tables)
{
foreach (DataRow dr in table.Rows)
{
//do stuff
I guess my question is twofold, like I said above. One would DataReader solve my problem and allow me to iterate through the data, and two how do I adapt the first code snippet above to support that?
Also, since I've seen it elsewhere, I'm using x64 on the application.
I am having trouble writing my datagrid changes to the database, i am trying to type in the changes on the grid and then when Button_Add_Car is pressed i execute this code and write changes to the database but nothing is being written to the database.
private void Button_Add_Car(object sender, RoutedEventArgs e)
{
SqlConnection cn = new SqlConnection();
DataSet dt = new DataSet();
SqlDataAdapter da;
SqlCommandBuilder cmdBuilder;
cn.ConnectionString = (String.Format("Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}", SQLFunctions.connectSQL.SQLSERVER_ID, SQLFunctions.connectSQL.SQLDatabaseName, SQLFunctions.connectSQL.SQLServerLoginName, SQLFunctions.connectSQL.SQLServerPassword));
cn.Open();
da = new SqlDataAdapter("SELECT * FROM Cars", cn);
cmdBuilder = new SqlCommandBuilder(da);
da.Fill(dt);
da.Update(dt);
cn.Close();
}
Am i on the right track using this method?
Am i using the correct SQL Query? I am confused between the SELECT/INSERT as i have found examples where people are using both to achieve what i want to do. Surely i should be using the INSERT statement.
I made my own custom SQL Command to manually insert into the database so it is in fact working:
SQLCmd("INSERT INTO Cars (Date, Time) VALUES(2014-10-10, '12:00:00')");
EDIT 1:
Thanks to marc_s i managed to achieve some sort of inserting but i believe i need to modify the value section to be inside an IF Statement which will check if it is a null or not and change value back to cr.Date and cr.Time as i am making use of a list. I am unsure of how to utilize the if statement in this way because it is currently entering blank rows, although its a step in the right direction:
CarRecord cr = new CarRecord();
carRecords.Add(cr);
SqlConnection con = new SqlConnection(String.Format(#"Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}", SQLFunctions.connectSQL.SQLSERVER_ID, SQLFunctions.connectSQL.SQLDatabaseName, SQLFunctions.connectSQL.SQLServerLoginName, SQLFunctions.connectSQL.SQLServerPassword));
con.Open();
SqlCommand comm = new SqlCommand("INSERT INTO Cars VALUES (#Date, #Time)", con);
SqlDataAdapter da = new SqlDataAdapter(comm);
da.SelectCommand.Parameters.Add(new SqlParameter("#Date", SqlDbType.NVarChar)).Value = DBNull.Value;
da.SelectCommand.Parameters.Add(new SqlParameter("#Time", SqlDbType.NVarChar)).Value = DBNull.Value;
da.SelectCommand.ExecuteNonQuery();
DataTable dt = new DataTable();
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.Update(dt);
con.Close();
lets take your first code example.
take a look at the last 3 lines, first thing you do is to copy data from the table Cars and store that into the DataSet named dt.
then immediately after you store this dataset back into the database, without actually doing any changes.
if dot net is smart enough it wont do anything, since you didn't change anything between the fill and the update call.
what you probably should be doing is get the dataset from the datagrid or similar and store that one instead.
or do as you have started on in your second example of when you identity that a row is updated take the data from that row and construct an insert (or update) query to the database.
I'm working in C# to combine queries from separate databases into one query/database. So far, I have queried what I need from the first connection (let's call it Connection1) and filled in the datatable
OleDbCommand dt = new OleDbCommand("SELECT blah FROM blah", DBConn.Connection1);
DataTable dt = new DataTable();
OleDbDataAdapter adapter1 = new OleDbDataAdapter(dt);
adapter1.Fill(dt);
Now, I need to read this datatable into a database with a brand new connection (call it Connection2). After this I will need to combine this database with the result of the other query in Connection2.
How can I go about reading this datatable into a brand new connection so that all the data in the datatable can be used with that through Connection 2?