Store A List Of Data In Mysql DataBase? - c#

i have a list of String Data i would Like to Store in my MySQL database Table in Column "Categories".
Is there a way to store it at a go because its a long list.`
public Class PickerView{
List<string> CategoriesPicker = new List<string>();
public Button SaveItemsButton = new Button();
public PickerView()
{
CategoriesPicker.Items.Add("Hotels & Travel");
CategoriesPicker.Items.Add("Restaurant");
CategoriesPicker.Items.Add("Wholesalers");
CategoriesPicker.Items.Add("Automotives");
CategoriesPicker.Items.Add("Pets");
CategoriesPicker.Items.Add("Musical Instruments Services");
CategoriesPicker.Items.Add("Specialty Food");
CategoriesPicker.Items.Add("Food");
CategoriesPicker.Items.Add("Boutique");
CategoriesPicker.Items.Add("Home & Gardens");
CategoriesPicker.Items.Add("Shopping");
CategoriesPicker.Items.Add("Education");
CategoriesPicker.Items.Add("Books,Mags,Music & Video");
CategoriesPicker.Items.Add("Fashion");
CategoriesPicker.Items.Add("Event Planning & Services");
CategoriesPicker.Items.Add("Arts & Craft");
CategoriesPicker.Items.Add("Local Services");
CategoriesPicker.Items.Add("NightLife(Bars..)");
SaveItemsButton.Clicked += SavedItemsButton_Clicked
}
private void SavedItemsButton_Clicked(object sender, System.EventArgs e)
{
string sqlstring = "server=; port= ; user id =;Password= ;Database=test;";
MySqlConnection conn = new MySqlConnection(sqlstring);
try
{
conn.Open();
}
catch (MySqlException ex)
{
throw ex;
}
string Query = "INSERT INTO test.maintable (Categories)values('" +(**//I DONT KNOW WHAT TO WRITE HERE TO SAVE ALL AT ONCE**) + "');";
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.ExecuteReader();
conn.Close();
}
}`
How do i save the list of items in CategoriesPicker in database when SaveItemsButton is clicked.

Simple use the mysql insert into statement.
insert into tbl1 values
(1, 'Name1', 1, null),
(2, 'Name2', 2, null),
(3, 'Name3', 1, null);
(3, 'Name3', 1, null) is of course the structure of tbl1
This will work in any language you use or even in comand line

MySQL (and MariaDB) don't have list-valued column types since that goes against first normal form in database design.
What you do instead is what #nbk suggested and, using whatever database framework you chose, insert multiple rows. Here's a sample table definition for MariaDB/MySQL if you don't have one already:
Microsoft's current recommended way of interacting with a database is Entity Framework Core. The documentation there can help you with connecting to a database, creating a table, adding rows to a table and saving all of that to the database.
Hope that helps!

I added using blocks to your code to ensure that your database objects are closed and disposed even if there is an error.
Set the query text only once, it stays the same for each iteration of the loop. Likewise the parameter is added outside the loop. Only the value of the parameter is changed inside the loop. We use .ExecuteNonQuery (not reader) for Insert, Update or Delete. .ExecuteReader is used for returning data.
private List<string> CategoriesPicker = new List<string>();
//add all the items to the list
private void SavedItemsButton_Clicked(object sender, System.EventArgs e)
{
string sqlstring = "server=; port= ; user id =;Password= ;Database=test;";
using (MySqlConnection conn = new MySqlConnection(sqlstring))
{
string Query = "INSERT INTO test.maintable (Categories)values(#Category);";
using (MySqlCommand cmd = new MySqlCommand(Query, conn))
{
cmd.Parameters.Add("#Category", MySqlDbType.VarChar);
try
{
conn.Open();
}
catch (MySqlException ex)
{
throw ex;
}
foreach (String item in CategoriesPicker)
{
cmd.Parameters["#Category"].Value = item;
cmd.ExecuteNonQuery();
}
}
}
}

Related

Bringing up pictures from a database as I search for the name

I need help with this program I'm trying to write. I'm a complete noob at this, so forgive my shortcomings but I'm trying to create a search feature, in which it completes the names from a database as soon as you write the first letter. I've done this succesfully, now I have to bring up pictures also from the same database, I'm getting some errors. Could you take a look at my code and tell me what's wrong? And also is this enough?
note: My aim is to bring up pictures AS they write the name.
void showpic(string queryStr)
{
SqlConnection conn = new SqlConnection(#"server adress");
conn.Open();
SqlCommand execute = new SqlCommand("SELECT Pernr from View_PhoneBook where DisplayName=" + textBox1.Text, conn);
try
{
StringCollection View_Phonebook = new StringCollection();
SqlDataReader reader = execute.ExecuteReader();
while (reader.Read())
{
View_Phonebook.Add(reader.GetString(0));
}
pictureBox1.ImageLocation.Equals("url" + View_Phonebook + ".jpg");
}
catch (Exception ex)
{
}
conn.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
showpic(textBox1.Text);
}
Add quotes to the string in this line, like so:
SqlCommand execute = new SqlCommand('SELECT Pernr from View_PhoneBook where DisplayName= #text', conn);
execute.Parameters.Add("text", SqlDbType.Text).Value = Textbox1.text;
I will suggest, you should do this using a StoredProc.
Its not a solution to the prob, but another way to do this.
That way you will not face any such probs.
Moreover, havign a StoredProc is better then constructing a query on every text change event.

WPF/SQL - how to get tables from a selected database into a ListView

Good evening,
i'm at the beginning of an IT apprenticeship and i've started my own little project. I've got following problem:
I've created in WPF a standard Login Window for getting SQL Connection Datas. This Window is working fine and i only can switch to the next window when the entered Login-Datas are correct. My problem is the second window. In the second one i have one ListBox for listing every Database from the connected Server. Next to this ListBox i've a ListView. In this ListView i want to see the tables from the selected Database.
Code for listing Databases:
SqlConnection GetConnection = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
try
{
this.libDatabase.Items.Clear();
DataTable databases = new DataTable("Databases");
using (IDbConnection connection = GetConnection)
{
IDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM sys.Databases";
connection.Open();
databases.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
}
this.libDatabase.Items.Clear();
foreach (DataRow row in databases.Rows)
this.libDatabase.Items.Add(row[0].ToString());
}
catch (SqlException)
{
this.libDatabase.Items.Clear();
this.libDatabase.Items.Add("Connection error");
}
catch (Exception ex)
{
MessageBox.Show("Error while loading available databases");
}
finally
{
GetConnection.Close();
}
libDatabase is the name of the ListBox.
This Code is working good and every Database is shown in my ListBox. But no i've a totally Blackout. How do i get the Tables from the selected Database into the ListView? I've tried the same way like i did with the Databases but with a different "SELECT"-Statement ==> "select * from {0}", listbox.SelectedItem
Here are different Codes i've tried but i think that i do something completely wrong.
First Version:
List<ListViewItem> gettables = new List<ListViewItem>();
if (libDatabase.SelectedItem != null)
{
SqlConnection con = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
string strSQL = string.Format("select * from {0}", libDatabase.SelectedItem);
SqlCommand cmd = new SqlCommand(strSQL, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
}
reader.Close();
con.Close();
}
Second Version:
SqlConnection GetConnection = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
try
{
this.libTables.Items.Clear();
DataTable tables = new DataTable("Tables");
using (IDbConnection connection = GetConnection)
{
IDbCommand command = connection.CreateCommand();
if (libDatabase.SelectedItem != null)
{
command.CommandText = string.Format("SELECT * FROM {0}", libDatabase.SelectedItem);
connection.Open();
tables.Load(command.ExecuteReader());
}
}
this.libTables.Items.Clear();
foreach (DataRow row in tables.Rows)
this.libTables.Items.Add(row[0].ToString());
}
catch (SqlException)
{
this.libTables.Items.Clear();
this.libTables.Items.Add("Connection error. Check server");
}
catch (Exception ex)
{
MessageBox.Show("Error while loading available tables" + ex);
}
finally
{
GetConnection.Close();
}
libTables is the name of the ListView.
Maybe i did it completely wrong or there's just one code block false.
Thank you for supporting.
Dave S.
Try this select statement instead:
command.CommandText = string.Format("SELECT * FROM {0}.sys.tables", libDatabase.SelectedItem);
As the database names are to be found in sys.databases within master, so too the tables are to be found within sys.tables for each database.
It pays to step through code of this nature with a debugger, and/or put a breakpoint at each meaningful location. Verify each sql statement built in the code is exactly what you intended, and execute each statement within Sql Management studio using the same permissions under which it is being executed within your code, to ensure the statement will produce the results you want.
Edit for triggering the table load:
You must also ensure the table-loading process is triggered by the appropriate action. In this case, it would most likely need to be triggered by the user selecting a database within the database listbox. You'll need to add an event handler for the SelectionChanged event to the listbox. (Note that I'm assuming you're not using the MVVM pattern based on the code samples you included in your question.)
Add the SelectionChanged attribute to your ListBox definition:
<ListBox Name="libDatabase" SelectionChanged="libDatabase_SelectionChanged">
And in the codebehind, define the event handler:
private void libDatabase_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if(libDatabase.SelectedItem != null)
{
// open a database connection and select your tables here.
}
}

Moving Data from DataSet to Oracle Database using C#

I've been squeezing my mind trying to figure out why my code isn't working.
I am trying to read from a DataSet that filled with data from access database and insert the data into an Oracle database which is created previously.
When I try the following code it won't work and although I use the try and catch block, when debugging it would freeze and won't show me any error.
if can see that I have commented out the block just right above my foreach loop..which works perfectly, Any help from you is so much appreciated :
private void button3_Click(object sender, EventArgs e)
{
string query1 = "Select * from Test;";
string StrQuery= "Insert Into TEST (ID, DATA) Values (:ID, :DATA)";
Conn = new OleDbConnection(connStr);
Conn.Open();
using (OleDbConnection connection1 = new OleDbConnection(connStr))
{
using (OleDbDataAdapter adapter1 = new OleDbDataAdapter(query1, connection1))
{
DataSet ds1 = new DataSet();
adapter1.Fill(ds1);
// no need for refilling DataGridView1.DataSource = ds.Tables[0]
// insterting the dataset into oracle
try
{
using (OracleConnection connect = new OracleConnection(oradb1))
{
connect.Open();
using (OracleCommand comma = new OracleCommand(StrQuery, connect))
{
/*comma.Parameters.Add(new OracleParameter(":ID", 2));
comma.Parameters.Add(new OracleParameter(":DATA", 2));
comma.ExecuteNonQuery();*/
foreach (DataRow drRow in ds1.Tables[0].Rows)
{
for (int i = 0; i < ds1.Tables[0].Columns.Count; i++)
{
comma.Parameters.Add(new OracleParameter(":ID", drRow[i]));
comma.Parameters.Add(new OracleParameter(":DATA", drRow[i]));
comma.ExecuteNonQuery();
}
}
connect.Close();
connect.Dispose();
}
}
}
catch (OracleException)
{
System.Diagnostics.Debugger.Break();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Conn.Close();
}
You are looping columns but adding the drRow[i] as values in the parameters.
I do not think this is what you intended.
skip the columns loop and add the first column value to id and second column value to data.
that should be what you wanted.... if not then describe a bit more...
Expanding on Judgemaik's answer, I believe you need to do something like this instead (can't really tell what the names of the columns in your access table are but you get the idea:
foreach (DataRow drRow in ds1.Tables[0].Rows)
{
comma.Parameters.Add(new OracleParameter(":ID", drRow["IDColumnFromAccessDB"]));
comma.Parameters.Add(new OracleParameter(":DATA", drRow["DATAColumnFromAccessDB"]));
comma.ExecuteNonQuery();
}
A similar approach is outlined in my answer here. In that particular case I was moving data from SQL Server Compact into Access, but the same idea could very well be used to move data between any two OleDb data sources.
It uses an OleDbDataAdapter to pull the source table into a DataTable, copies it over to another DataTable, and then uses another OleDbDataAdapter to update the corresponding table in the destination database.

Retrieve/insert data using SQLiteDataAdapter

I'm currently creating a small application using Windows Forms and SQLite. After reading some tutorials I implemented this method for data retrieval:
public DataTable GetDataTable(ref SQLiteDataAdapter adapter, string sql)
{
DataTable dt = new DataTable();
// Connect to database.
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
// Create database adapter using specified query
using (adapter = new SQLiteDataAdapter(sql, connection))
// Create command builder to generate SQL update, insert and delete commands
using (SQLiteCommandBuilder command = new SQLiteCommandBuilder(adapter))
{
// Populate datatable to return, using the database adapter
adapter.Fill(dt);
}
return dt;
}
(As well as another GetDataTable which doesn't take an SQLiteDataAdapter as parameter)
I have three classes, let's call them UI, Link and Database. The UI does nothing but displaying the data and raising events upon user interaction. The Link creates the Database and a SQLiteDataAdapter, retrieves a data table through the method mentioned above, and binds it to a data grid view on the UI. The user cannot alter the table through the data grid view, but should do so through some text boxes. (does this make binding the table to the dgv obosolete?)
What's the best way to get the user input from the text boxes to the database, using the adapter? Or should I use DataReader and some Insert method instead of an adapter?
As of know, the UI exposes its controls through Get-methods. Is there a better solution?
private void Initialize()
{
// Subscribe to userInterface events
userInterface.DataGridViewSelectionChanged += new EventHandler(userInterface_DataGridViewSelectionChanged);
userInterface.NewClicked += new EventHandler(userInterface_NewClicked);
userInterface.SaveClicked += new EventHandler(userInterface_SaveClicked);
// Get dataGridView from userInterface and bind to database
bindingSource = new BindingSource();
bindingSource.DataSource = database.GetDataTable(ref adapter, "SELECT * FROM SomeTable");
userInterface.GetDataGridView().DataSource = bindingSource;
}
void userInterface_DataGridViewSelectionChanged(object sender, EventArgs e)
{
if (userInterface.GetDataGridView().SelectedRows.Count != 0)
{
DataGridViewRow row = userInterface.GetDataGridView().SelectedRows[0];
userInterface.GetIDTextBox().Text = row.Cells["PrimaryKey].Value.ToString();
userInterface.GetOtherIDTextBox().Text = row.Cells["ForeignKey"].Value.ToString();
DataTable dt = database.GetDataTable("SELECT * from SomeTable WHERE ForeignKey=" + row.Cells["ForeignKey"].Value);
userInterface.GetLastNameTextBox().Text = dt.Rows[0]["LastName"].ToString();
userInterface.GetFirstNameTextBox().Text = dt.Rows[0]["FirstName"].ToString();
userInterface.GetCompanyTextBox().Text = dt.Rows[0]["Company"].ToString();
}
}
void userInterface_NewClicked(object sender, EventArgs e)
{
// Get all text boxes and clear them
// Let the UI take care of this by itself?
}
void userInterface_SaveClicked(object sender, EventArgs e)
{
// Get text/data from all text boxes and insert (or update if editing table) into database
// adapter.Update(...)?
}
Cheers!
INSERT, UPDATE and DELETE operations are the working of a DbCommand. You need a different method that takes the sql string and a collection of SQLiteParameter that you use for the INSERT.
I will try to write some pseudocode for the INSERT operation
public class MyHelperClass
{
public static int InsertCommand(string sql, SQLiteParameter[] parameters)
{
int result = 0;
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
using (SQLiteCommand cmd = new SQLiteCommand(sql, connection))
{
cmd.Parameters.AddRange(parameters);
result = cmd.ExecuteNonQuery();
}
return result;
}
}
Now you have to build the parameter array to pass to the help method and this should be done from your UI code
string sqlCommand = "INSERT INTO table1 (FirstName, LastName) VALUES (#fName, #lName)";
SQLiteParameter[] p = new SQLiteParameter[2];
p[0] = new SQLiteParameter("#fName", TextBox1.Text);
p[1] = new SQLiteParameter("#lName", TextBox2.Text);
int rowAdded = MyHelperClass,InsertCommand(sql, p);
The operation for the UPDATE and DELETE command are similar. Also I suggest you to add a version of your GetDataTable that accepts a parameter array instead of building sql commands with string concatenation. As repetead innumerable times here string concatenation leads to errors and, worst of all, to weak code easily exposed to sql injection.

How to show data using datagrid with C# + SQL Server

I want to ask more to show data from SQL Server to WinForm using a datagrid.
I've been creating a datagrid and the stored procedure to show data is
ALTER PROC [dbo].[SP_GetData]
AS
SELECT nama , nim
FROM tabledata
and I've created the function to access the database and the stored procedure in C#
string Sp_Name = "dbo.SP_GetData";
SqlConnection SqlCon = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=.");
SqlCon.Open();
SqlCommand SqlCom = new SqlCommand(Sp_Name , SqlCon);
SqlCom.CommandType = CommandType.StoredProcedure;
List<mahasiswaData> listMahasiswa = new List<mahasiswaData>();
using (SqlDataReader sqlDataReader = SqlCom.ExecuteReader())
{
if (sqlDataReader.HasRows)
{
while (sqlDataReader.Read())
{
mahasiswaData DataMhs = new mahasiswaData();
DataMhs.Nama = sqlDataReader["Name"].ToString();
DataMhs.Umur = Convert.ToInt32(sqlDataReader["Age"]);
listMahasiswa.Add(DataMhs);
}
}
}
SqlCon.Close();
return listMahasiswa;
and finally, in the show button I add this code
dgvmahasiswa.DataSource = new MahasiswaDB().LoadMahasiswa();
Could somebody tell me where the fault is or the alternatives one?
Thank You So Much! :D
Some things to think about:
At the moment, if your code runs into exceptions, you'll leave a
SqlConnection hanging around; you've used the using pattern for your
SqlDataReader; you should extend it to all of your disposable
objects.
You are swallowing exceptions; if your query fails, the connection
cannot be made, or something else happens, you'll never really know - your function will just return null.
Is it possible for name or age to be null? Age to be non-numeric?
There's no test for any unexpected values, which you'll also never
know about.
If you don't have any records, you'll return an empty list. Is this
desired? Or would you prefer to know there were no records?
You might prefer to look at something like this:
public List<mahasiswaData> GetData(){
List<mahasiswaData> gridData = new List<mahasiswaData>();
try{
using(SqlConnection conn = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=."))
{
using(SqlCommand command = new SqlCommand())
{
command.Connection = conn;
command.CommandType = CommandType.StoredProcedure;
command.Text = "dbo.SP_GetData";
using(SqlDataReader reader = command.ExecuteReader())
{
if(reader.HasRows){
while(reader.Read())
{
object rawName = reader.GetValue(reader.GetOrdinal("Name"));
object rawAge = reader.GetValue(reader.GetOrdinal("Age"));
if(rawName == DBNull.Value || rawAge == DBNull.Value)
{
//Use logging to indicate name or age is null and continue onto the next record
continue;
}
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = Convert.ToString(rawName),
Umur = Convert.ToInt32(rawAge)
});
}
}
else{
//Use logging or similar to record that there are no rows. You may also want to raise an exception if this is important.
}
}
}
}
}
catch(Exception e)
{
//Use your favourite logging implementation here to record the error. Many projects use log4Net
throw; //Throw the error - display and explain to the end user or caller that something has gone wrong!
}
return gridData;
}
Note that if you are sure that age or name will never be null then you can simplify the middle section:
while (reader.Read())
{
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = reader.GetString(reader.GetOrdinal("Name")),
Umur = reader.GetInt32(reader.GetOrdinal("Age"))
});
}

Categories

Resources