I have tried nearly every solution on this website, but I can't solve this problem. I have data that has been retrieved from a database through an ODBC connection. The data is there. It will go into a Data Grid View just fine, but I can't get this data to go into my local SQL database. Please tell me what I'm doing wrong.
public partial class frmNorth : Form
{
// variables for the connections
private OdbcConnection epnConnection = new OdbcConnection();
private SqlConnection tempDbConnection = new SqlConnection();
public frmNorth()
{
InitializeComponent();
// This is for the ePN DB
epnConnection.ConnectionString = #"Dsn=ePN; uid=username; pwd=myPa$$Word";
// This is for the local DB
tempDbConnection.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\TempDB.mdf;Integrated Security=True";
}
private void btnLoadData_Click(object sender, EventArgs e)
{
try
{
//===This part works just fine===============================================================
epnConnection.Open();
string epnQuery = "SELECT FNCL_SPLIT_REC_ID, PROJ_ID, SALES_SRC_PRC " +
"FROM PROJ_FNCL_SPLIT " +
"WHERE PROJ_ID=" + textBox1.Text + "";
OdbcCommand epnCommand = new OdbcCommand(epnQuery, epnConnection);
epnCommand.CommandTimeout = 0;
//This connects the data to the data table
OdbcDataAdapter da = new OdbcDataAdapter(epnCommand);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
//===========================================================================================
//======The part below is the part that wont work. The data wont go into the SQL database====
tempDbConnection.Open();
string tempSql = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
tempSql = "INSERT INTO tblTemp (FNCL_SPLIT_REC_ID, PROJ_ID, SALES_SRC_PRC) VALUES ('"
+ dt.Rows[i]["FNCL_SPLIT_REC_ID"].ToString().Trim() + "','"
+ dt.Rows[i]["PROJ_ID"].ToString().Trim() + "','"
+ dt.Rows[i]["SALES_SRC_PRC"].ToString().Trim() + "');";
SqlCommand tempCommand = new SqlCommand(tempSql, tempDbConnection);
tempCommand.ExecuteNonQuery();
}
// There are no errors. The data just doesn't save to the database.
//===========================================================================================
epnConnection.Close();
tempDbConnection.Close();
}
catch (Exception ex)
{
epnConnection.Close();
tempDbConnection.Close();
MessageBox.Show("Error " + ex);
}
}
}
}
//+++++++++++++++++++This is what the table looks like+++++++++++++++++++++++++++++++++++++++++++++++
CREATE TABLE [dbo].[tblTemp] (
[FNCL_SPLIT_REC_ID] INT NOT NULL,
[PROJ_ID] NCHAR (10) NULL,
[SALES_SRC_PRC] MONEY NULL,
PRIMARY KEY CLUSTERED ([FNCL_SPLIT_REC_ID] ASC)
Like I said no errors come up. The data just doesn't save to the database.
"INSERT INTO tblTemp (FNCL_SPLIT_REC_ID, PROJ_ID, SALES_SRC_PRC) VALUES ("
+ dt.Rows[i]["FNCL_SPLIT_REC_ID"].ToString().Trim() + ",'"
+ dt.Rows[i]["PROJ_ID"].ToString().Trim() + "',"
+ dt.Rows[i]["SALES_SRC_PRC"].ToString().Trim() + ");";
Removed the ' ' between FNCL_SPLIT_REC_ID as it is int and SALES_SRC_PRC since it is money.
I found no error on code you implemented. I found that connection definition for mdf file was wrong.
|DataDirectory| setting path to the folder where application run. In this case if we run in Debug mode, it will create separate application exe in Debug\bin folder with application resources like .mdf files. or in Release mode it will create particular folders inside release folder. So you need to change Database File name for database connection or you need to give entire directory path for connection string. Example
tempDbConnection.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\TempDB.mdf;Integrated Security=True";
}
replace
tempDbConnection.ConnectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Promod\Documents\Visual Studio 2012\Projects\Contribution1\Contribution1\bin\Debug\TempDB.mdf;Integrated Security=True";
Related
This program is supposed to take a csv file and load it to a sqlite database that the use specifies a path to. Rather than trying to load the values to the selected database it creates a copy of the database in the debug folder and then throws an error because the table doesn't exist in the new db. I can't find where it's deciding to make a new file rather than using the existing one.
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + db3FilePath + "; Synchronous=Off"))
{
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
conn.Open();
foreach (KeyValuePair<string, CSVRecord> kvp in csvDictionary.Skip(1))
{
//checks for duplicate records
cmd.CommandText = "SELECT COUNT(*) FROM Accounts WHERE SDM_ACCT='" + kvp.Value.sdmacct + "'";
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count < 1)
{
WritetoDatabase.WritetoAccountsTable(kvp.Value.description, kvp.Value.priority, db3FilePath);
WritetoDatabase.WritetoDirectoryTable(kvp.Value.number, kvp.Value.active, db3FilePath);
recordCount++;
//updates the progress bar and text field showing %
int progress = y++ * 100 / (csvDictionary.Keys.Count -1);
progressBar1.Invoke((MethodInvoker)(() => progressBar1.Value = progress));
progressBar1.Invoke((MethodInvoker)(() => progressBar1.Update()));
lblStatus.Invoke((MethodInvoker)(() => lblStatus.Text = "Writing records to database: " + progress.ToString() + "% Complete"));
lblStatus.Invoke((MethodInvoker)(() => lblStatus.Update()));
}
else
{
WritetoDatabase.WritetoDirectoryTable(kvp.Value.number, kvp.Value.active, db3FilePath);
y++;
}
}
conn.Close();
}
}
Here is a copy of the method that writes to the database.
public static int WritetoAccountsTable(string Comment, int PriorityInt, string filePath)
{
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + filePath + "; Synchronous=Off"))
{
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
conn.Open();
cmd.CommandText = #"INSERT INTO Accounts(Description,Priority)
values(#Comment,#PriorityInt)";
cmd.Parameters.AddWithValue("#Comment", Comment);
cmd.Parameters.AddWithValue("#PriorityInt", PriorityInt);
return cmd.ExecuteNonQuery();
}
}
}
I've changed everything I can think of trying to find what's causing the problem. Maybe you will see something I can't.
One of the all-time dumbest things I have seen break a program. The Connection String using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + filePath + "; Synchronous=Off")) has "data source". If it is not capitalized, "Data Source", it doesn't recognize it and goes to a default setting.
I am writing a C# application
It is an offline test application
It imports a large data file in the form of a .csv file
This file is chosen by the user using a form
I then want to store the information contained in this .csv file in the form of a local database such that I can perform sql queries
I am using Visual Studio 2012
I have never setup an sql database before and only have limited experience using sql on existing databases
My attempt so far is:
Solution explorer > Add new file > Local Database (.sdf file)
Database Explorer > Tables > Create Table
I have then added column names for all the fields setting one as my primary key
I have attempted to add a single dataset to my data table with no luck
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\MyDatabase.sdf";
SqlCeConnection sqlConnection = new SqlCeConnection("datasource=" + dbfile);
SqlCeDataAdapter sqlAdapter = new SqlCeDataAdapter("select * from MyTable", sqlConnection);
AMCCoreSignalsDBDataSet sqlData = new AMCCoreSignalsDBDataSet();
sqlAdapter.Fill(sqlData);
string strCSVDataLine = "1,2,3,four"
sqlData.Tables[0].Rows.Add(new object[] { strCSVDataLine });
sqlAdapter.Update(sqlData);
sqlConnection.Close();
This code fails to work
How can I use C# to populate my database with the .csv data?
Is my method incorrect/incomplete?
Is there a better way to do this?
The reason I would like to use sql is because there is a lot of data. I could create a class structure to contain the data however it would also mean creating many different filter functions. Which SQL already contains...
Problems were due to blank values occurring in the .csv file
This was my fix
public void Import(string csvfname)
{
string password;
string cacheDatabase;
string connectionString;
System.IO.StreamReader objFile;
string strCommand;
string lineHeader;
string line;
string[] arrLineData;
cacheDatabase = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\MyDatabase.sdf"; ;
password = "";
connectionString = string.Format("DataSource=\"{0}\"; Password='{1}'", this.cacheDatabase, this.password);
objFile = new System.IO.StreamReader(csvfname);
lineHeader = objFile.ReadLine();
while (!objFile.EndOfStream)
{
line = objFile.ReadLine();
arrLineData = line.Split(',');
try
{
sqlConnection = new SqlCeConnection(connectionString());
strCommand = "INSERT INTO MyTable VALUES ('" + arrLineData[0] + "', '" + arrLineData[1] + "', '" + arrLineData[2] + "')";
SqlCeCommand sqlCommand = new SqlCeCommand(strCommand, sqlConnection);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
catch (Exception exc)
{
MessageBox.Show("Error in Import(): " + exc.Message);
}
}
}
Ok, I have been having a problem the last few days with my database not updating. I can read the data fine and I'm not getting any exceptions either. I'm trying to update the database then I try to read values again after the update (during same run), and they still hold the original values, so it doesn't seem to be an issue with the database being copied to another folder (I'm using Copy if newer yet neither database is being updated).
Here is the code I'm using. As you can see I tried a few different approaches, none of which worked yet.
public void UpdateDatabaseInStock(string itemName, string tableName)
{
DataSet data = new DataSet("Items");
int val;
//get the file path to the database as a string
string dbfile =
new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName +
"\\Database\\GameData.sdf";
//connect to the database
using (SqlCeConnection cntn = new SqlCeConnection("datasource=" + dbfile))
{
//create an adapter to pull all data from the table
using (SqlCeDataAdapter adpt = new SqlCeDataAdapter
("SELECT * FROM " + tableName + " WHERE Name LIKE '%" + itemName + "%'", cntn))
{
//put the data into a DataSet
adpt.Fill(data);
cntn.Close();
}
//fill the data from the Items table into a DataTable to return.
DataTable itemTable = data.Tables[0];
DataRow a = itemTable.Rows[0];
val = (short)a.ItemArray[3] - 1;
dbfile = "";
data.Dispose();
itemTable.Dispose();
SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = cntn;
cntn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE " + tableName + " SET [In Stock] = #Value WHERE [Name] = '#ItemName'";
//cmd.Parameters.Add("#Value", SqlDbType.SmallInt);
//cmd.Parameters["#Value"].Value = val;
//cmd.Parameters.Add("#ItemName", SqlDbType.NChar, 75);
//cmd.Parameters["#ItemName"].Value = itemName;
cmd.Parameters.AddWithValue("#Value", val);
cmd.Parameters.AddWithValue("#ItemName", itemName);
cmd.ExecuteNonQuery();
//close the conenction
cntn.Close();
cmd.Dispose();
}
}
Any ideas to get it to actually update?
Just a hunch (can't corroborate this on msdn): could it be that using nchar(75) adds spaces to the parameter, thereby causing the WHERE clause to fail?
I have problem with an INSERT statement. I get data from gridviev and it works fine, but I can't insert them into table
private void button3_Click(object sender, EventArgs e)
{
int amorplanid = 0;
int idn = 0;
DateTime datum;
double interest = 0;
double principal = 0;
double payment = 0;
double newprincipal = 0;
string nizz = "";
string[] niz= new string[7];
for (int x = 0; x < dataGridView1.Rows.Count-1; x++)
{
for (int j = 0; j < dataGridView1.Rows[x].Cells.Count; j++)
{
nizz += dataGridView1.Rows[x].Cells[j].Value.ToString()+".";
}
niz = nizz.Split('.');
amorplanid = System.Convert.ToInt32(niz[0]);
idn = System.Convert.ToInt32(niz[1]);
// datum = System.Convert.ToDateTime(niz[2]);
datum = DateTime.Now;
interest = System.Convert.ToDouble(niz[3]);
principal = System.Convert.ToDouble(niz[4]);
payment = System.Convert.ToDouble(niz[5]);
newprincipal = System.Convert.ToDouble(niz[6]);
String insert = #"INSERT INTO AmortPlanCoupT(ID, AmortPlanID, CoupDate, Interest, Principal, Payxment, NewPrincipal) VALUES (" + idn + "," + amorplanid + "," + datum + "," + (float)interest + "," + (float)principal + "," + (float)payment + "," + (float)newprincipal + ")";
SqlConnection myconn = new SqlConnection(conn);
// String MyString = #"INSERT INTO Employee(ID, FirstName, LastName) VALUES(2, 'G', 'M')";
try
{
myconn.Open();
SqlCommand cmd = new SqlCommand(insert, myconn);
cmd.ExecuteNonQuery();
myconn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
label14.Text = niz[0];
}
I have created a Windows console app to test :
I have table test with two columns id (int) , leto (float);
SqlConnection MyConnection = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App_Data\Database1.mdf;Integrated Security=True;User Instance=True");
try
{
MyConnection.Open();
String MyString = #"INSERT INTO test(id, leto) VALUES(2, 2)";
SqlCommand MyCmd = new SqlCommand(MyString, MyConnection);
MyCmd.ExecuteScalar();
MyConnection.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
I've been trying different stuff to write data to table, and just can't get them there.
As I've said before on this site - the whole User Instance and AttachDbFileName= approach is flawed - at best! Visual Studio will be copying around the .mdf file and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. Database1)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\SQLEXPRESS;Database=Database1;Integrated Security=True
and everything else is exactly the same as before...
Before you go any further, you should rewrite your code to use parameters, instead of string concatenation.
I have two DataGridView controls.
For the second one, I just copy-pasted the code from the first and changed where the difference was. But I get an error at the second when I want to view the result of my SQL code.
Translated in English the error show something like that there was no value given to at least one required parameter.
private void button1_Click(object sender, EventArgs e)
{
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=save.mdb";
try
{
database = new OleDbConnection(connectionString);
database.Open();
date = DateTime.Now.ToShortDateString();
string queryString = "SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID) "
+ "LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila"
+ "WHERE users.ID= " + a.ToString();
loadDataGrid(queryString);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
public void loadDataGrid(string sqlQueryString)
{
OleDbCommand SQLQuery = new OleDbCommand();
DataTable data = null;
dataGridView1.DataSource = null;
SQLQuery.Connection = null;
OleDbDataAdapter dataAdapter = null;
dataGridView1.Columns.Clear(); // <-- clear columns
SQLQuery.CommandText = sqlQueryString;
SQLQuery.Connection = database;
data = new DataTable();
dataAdapter = new OleDbDataAdapter(SQLQuery);
dataAdapter.Fill(data);
dataGridView1.DataSource = data;
dataGridView1.AllowUserToAddRows = false;
dataGridView1.ReadOnly = true;
dataGridView1.Columns[0].Visible = true;
}
private void button2_Click(object sender, EventArgs e)
{
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=save.mdb";
try
{
database = new OleDbConnection(connectionString);
database.Open();
date = DateTime.Now.ToShortDateString();
string queryString = "SELECT skupaj_kalorij "
+ "FROM obroki_save "
+ "WHERE users.ID= " + a.ToString();
loadDataGrid2(queryString);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
public void loadDataGrid2(string sqlQueryString)
{
OleDbCommand SQLQuery = new OleDbCommand();
DataTable data = null;
dataGridView2.DataSource = null;
SQLQuery.Connection = null;
OleDbDataAdapter dataAdapter = null;
dataGridView2.Columns.Clear(); // <-- clear columns
SQLQuery.CommandText = sqlQueryString;
SQLQuery.Connection = database;
data = new DataTable();
dataAdapter = new OleDbDataAdapter(SQLQuery);
dataAdapter.Fill(data);
dataGridView2.DataSource = data;
dataGridView2.AllowUserToAddRows = false;
dataGridView2.ReadOnly = true;
dataGridView2.Columns[0].Visible = true;
}
You'd be far better off reading and doing this tutorial:
http://msdn.microsoft.com/en-us/library/ms171884(v=VS.80).aspx
It will probably take about 20 minutes to complete
And then (as needed) the rest of them (google for Data Walkthroughs)
They will teach you how to do your data access properly and, after becoming familiar with the advanced tools in Visual Studio for connecting to databases, you'll be able to generate an app that will show database contents in a grid, and save them back to the db, faster than it took you to even write your post here..
The code will be high performance, more secure and easier to write than what you have here - the code you have here is low quality, prone to SQL injection attacks, not modular or arranged in a way that is suited to the language youre using and takes a long time to write; all in, it has no good points at all (please don't be offended)
I thoroughly recommend scrapping the entire thing and starting again, doing things in the way advocated by Microsoft's tutorial. It might seem like the wrong thing to do after you've poured so many hours into this broken, bad way of doing things, but trust me.. You'll be glad you did; 20 minutes investment now will save you thousands of hours of coding in the future
One final point, if your database data doesnt seem to be saving changes when you do things the way the tutorial tells you to, click on the database in Solution Explorer and change "Copy to Output Directory" to "Copy if Newer" - c# is updating your database but youre either looking in the wrong DB to check whether it worked, or Visual Studio is replacing your edited database with a new one every time you start your app
I think the problem is in private void button2_Click() with
a.ToString();
What's a?
Try putting quotes around a.Tostring():
string queryString = "SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID)"
+ " LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila "
+ " WHERE users.ID= '" + a.ToString() + "'";
or use string.format():
string queryString = string.format("SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID)"
+ " LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila "
+ " WHERE users.ID= '{0}'", a);