I have a basic form with an 'Add Recipe' button which is meant to write the following to me SQL Server Express database:
Recipe Name
Recipe Ingredients
Recipe Instructions
Recipe Image
The form is located at the bottom of the question and when I click the 'Add Recipe' button it makes a call to the updatedate() method, this method looks like so:
private void updatedata()
{
// filestream object to read the image
// full length of image to a byte array
try
{
// try to see if the image has a valid path
if (imagename != "")
{
FileStream fs;
fs = new FileStream(#imagename, FileMode.Open, FileAccess.Read);
// a byte array to read the image
byte[] picbyte = new byte[fs.Length];
fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
//open the database using odp.net and insert the lines
string connstr = #"Data Source=.;Initial Catalog=RecipeOrganiser;Persist Security Info=True;User ID=sa";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
string query;
query = "insert into Recipes(RecipeName,RecipeImage,RecipeIngredients,RecipeInstructions) values (" + textBox1.Text + "," + " #pic" + "," + textBox2.Text + "," + textBox3.Text + ")";
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "pic";
picparameter.Value = picbyte;
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add(picparameter);
cmd.ExecuteNonQuery();
MessageBox.Show("Image successfully saved");
cmd.Dispose();
conn.Close();
conn.Dispose();
Connection();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
My problem is when ever I click the 'Add recipe' button with the information populated, it freezes for around 30 seconds and then displays the following error, I have checked that the SQL Server services are running which thy are. Can anyone offer ay advice what I am doing wrong here?
Image of Form
string connstr = #"Data Source=.;Initial Catalog=RecipeOrganiser;Persist Security Info=True;User ID=sa";
needs to be
string connstr = #"Server=localhost\{SERVER_NAME};Database=RecipeOrganiser;Trusted_Connection=True;";
you can get the SERVER_NAME from the property value "Name" user the SQL server properties
Use the following link
SqlConnection con = new SqlConnection("Data Source=servername\\SQLEXPRESS;Initial Catalog=databasename;User ID=sa;Password=yoursqlserverpassword");
Hope it will help you
your connection string doesn't look good to me ... try using .Net SqlConnectionStringBuilder class to create a valid connection string ... set DataSource, InitialCatalog and IntegratedSecurity or UserId and Password properties
Related
I'm trying to reuse a connection string created from a DataGridView. I can't seem to translate the value in the Settings.settings file to a usable connection string. Any ideas of what the Connection_String SHOULD look like?
Error:
Format of the initialization string does not conform to specification starting at index 0.
Code:
// This fills the gridview
this.loanacctTableAdapter.FillBy(this.innovate_Loan_ServicingDataSet.loanacct, ((decimal)(System.Convert.ChangeType(acctrefnoToolStripTextBox.Text, typeof(decimal)))));
// This tries to use the same connection
Connection_String = SpecialSetting.ConnectionString.ToString();
Command = "SELECT acctrefno FROM loanacct WHERE acctrefno = " + AcctrefnoToolStripTextBox.Text + "";
SqlConnection Conn = new SqlConnection(Connection_String);
SqlCommand Comm1 = new SqlCommand(Command, Conn);
Conn.Open();
SqlDataReader DR1 = Comm1.ExecuteReader();
if (DR1.Read())
{
textBox1.Text = DR1.GetValue(0).ToString();
textBox1.ReadOnly = true;
}
Conn.Close();
Settings.Designer.cs
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
[global::System.Configuration.DefaultSettingValueAttribute("Data Source=ILSVUPGRADE01;Initial Catalog=Innovate_Loan_Servicing;Integrated Secu" +
"rity=True")]
public string Innovate_Loan_ServicingConnectionString {
get {
return ((string)(this["Innovate_Loan_ServicingConnectionString"]));
ConnectionString is simply a String. I suggest to use the SqlConnectionStringBuilder Class. It makes it much easier to create a valid connection string.
You can get the full ConnectionString then with .ToString()
The solution ended up being the difference between Windows Forms and ASP.NET. I needed to find the configuration in the Settings.settings file and drill down. Windows forms stores the connection string as "Properties.Settings.Default. name of connection here.ToString(); The command and connection can then be set simply. ASP.NET sets the connection string under ConfigurationSettings.AppSettings("myConnectionString").
My code ended up looking like this.
string Connection_String = Properties.Settings.Default.Innovate_Loan_ServicingConnectionString.ToString();
string Command = "SELECT acctrefno, loan_number, [shortname], [loan_group_no] FROM loanacct WHERE acctrefno = " + acctrefnoToolStripTextBox.Text + "";
SqlConnection Conn = new SqlConnection(Connection_String);
SqlCommand Comm1 = new SqlCommand(Command, Conn);
Conn.Open();
SqlDataReader DR1 = Comm1.ExecuteReader();
if (DR1.Read())
etc.
I am extremely new to C# web development (or any development for that matter) but I am trying to figure out how to save the results from a SQL query to a variable. I think I understand the process, but many of the examples I am finding on the Web use a SqlConnection statement. My copy of Visual Studio does not seem to have that command (pretty sure I am using the wrong word here). What am I missing either softwarewise or knowledgewise accomplish my task?
Thank you in advance for your help.
Dep
It depends on what you want to do: insert, update, get data. It also depends if you want to use an ORM library or not. I all depends. The code that I copy below is an example of how to retrieve a DataTable using Ado.Net (as you mentioned SqlConnection):
You have to use:
using System.Data;
using System.Data.SqlClient;
This is the code for retrieving a DataTable
private DataSet ExecuteDataset(string query)
{
var conn = new SqlConnection("Data Source=" + Server + ";Initial Catalog=" + Database + ";User Id=" + Username + ";Password=" + Password + ";");
DataSet ds;
try
{
conn.Open();
ds = new DataSet();
var da = new SqlDataAdapter(query, conn);
da.Fill(ds);
}
catch (Exception)
{
throw;
}
finally
{
conn.Dispose();
conn.Close();
}
return ds;
}
private DataSet ExecuteDataset(string query, SqlParameter[] parametros)
{
var conn = new SqlConnection("Data Source=" + Server + ";Initial Catalog=" + Database + ";User Id=" + Username + ";Password=" + Password + ";");
DataSet ds;
try
{
conn.Open();
SqlCommand command = conn.CreateCommand();
command.CommandText = query;
foreach (SqlParameter p in parametros)
{
command.Parameters.Add(p);
}
ds = new DataSet();
var da = new SqlDataAdapter(command);
da.Fill(ds);
}
catch (Exception)
{
throw;
}
finally
{
conn.Dispose();
conn.Close();
}
return ds;
}
This is the code for running a query that does not expect result with and without parameters:
private void ExecuteNonQuery(string query)
{
var conn = new SqlConnection("Data Source=" + Server + ";Initial Catalog=" + Database + ";User Id=" + Username + ";Password=" + Password + ";");
try
{
conn.Open();
SqlCommand command = conn.CreateCommand();
command.CommandText = query;
command.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
finally
{
conn.Dispose();
conn.Close();
}
}
private void ExecuteNonQuery(string query, SqlParameter[] parametros)
{
var conn = new SqlConnection("Data Source=" + Server + ";Initial Catalog=" + Database + ";User Id=" + Username + ";Password=" + Password + ";");
try
{
conn.Open();
SqlCommand command = conn.CreateCommand();
command.CommandText = query;
foreach (SqlParameter p in parametros)
{
command.Parameters.Add(p);
}
command.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
finally
{
conn.Dispose();
conn.Close();
}
}
Here is the simplest example I can think of, take note of the using statements and comments
using System;
using System.Data;
using System.Data.SqlClient;
namespace DataAccess
{
class Program
{
static void Main(string[] args)
{
//Use your database details here.
var connString = #"Server=localhost\SQL2014;Database=AdventureWorks2012;Trusted_Connection=True;";
//Enter query here, ExecuteScalar returns first column first row only
//If you need to return more records use ExecuteReader/ExecuteNonQuery instead
var query = #"SELECT [AccountNumber]
FROM [Purchasing].[Vendor]
where Name = #Name";
string accountNumber = string.Empty;
//Using statement automatically closes the connection so you don't need to call conn.Close()
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(query, conn);
//Replace #Name as parameter to avoid dependency injection
cmd.Parameters.Add("#Name", SqlDbType.VarChar);
cmd.Parameters["#name"].Value = "Michael";
try
{
conn.Open();
//Cast the return value to the string, if it's an integer then use (int)
accountNumber = (string)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.WriteLine(accountNumber);
//ReadKey just to keep the console from closing
Console.ReadKey();
}
}
}
If you are really new to C# with SQL Server, I would recommend to start from scratch using one of the tutorials shown here. It provides a lot of information in a step-by-step manner:
The basics
Clearly definition of the core ceoncepts
How to setup dependencies to get started
How to choose between development models (code, model vs. database first)
How to write queries
and much more.
Using SqlConnection is a valid choice, but requires more effort in writing the queries for doing basic stuff like selecting, updating, deleting or inserting data. You actually have to construct the queries and take care to build and dispose the commands.
On a related note:
The new way of doing all database-related activities in C# or .NET would be to harness Entity Framework (EF), and try to move away from any ADO.NET-based code. The latter still exists and hasn't been marked as obsolete, though. You may want to use ADO.NET for small apps or for any PoC tasks. But, otherwise, EF is the way to go.
EF is an ORM, and is indeed built as a repository pattern and generates a conceptual layer for us to work with. All of the nuances of the connection and command are completely encapsulated from us. This way, we don't have to meddle with these bare-bones.
If you want to do it well, you have to edit a file named Web.config in your project and put something like this inside (with your own DB data):
<connectionStrings >
<add
name="myConnectionString"
connectionString="Server=myServerAddress;Database=myDataBase;User ID=myUsername;Password=myPassword;Trusted_Connection=False;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
Then, in the code, you can use it with:
SqlConnection con = new SqlConnection(
WebConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString);
Finally you can do that you want with "con", for example:
string queryString = "SELECT name, surname FROM employees";
SqlCommand command = new SqlCommand(queryString, con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader["name"], reader["surname"]));
}
}
finally
{
reader.Close();
}
i use this nuget library.
https://www.nuget.org/packages/SqlServerDB_dotNET/
using SqlServerDB;
string server = #"INSTANCE\SQLEXPRESS";
string database = "DEMODB";
string username = "sa";
string password = "";
string connectionString = #"Data Source="+ server + ";Initial Catalog="+ database + "; Trusted_Connection=True;User ID="+ username + ";Password="+ password + "";
DBConnection db_conn = new DBConnection(connectionString);
Console.WriteLine("IsConnected: " + db_conn.IsConnected());
if (db_conn == null || !db_conn.IsConnected())
{
Console.WriteLine("Connessione non valida.");
return;
}
string sql = "SELECT ID, Message FROM Logs ORDER BY IDLic;";
DataTable dtLogs = db_conn.SelectTable(sql);
if (dtLogs == null || dtLogs.Rows.Count == 0)
return;
// Loop with the foreach keyword.
foreach (DataRow dr in dtLogs.Rows)
{
Console.WriteLine("Message: " + dr["Message"].ToString().Trim());
}
I'm trying to connect to a SQL Server on a local machine, run a SQL command against it and log the results. The code keeps failing at making the connection to the server.
I can't quite see what I'm doing wrong. Everything I've searched for either doesn't apply to this method or seems to match what I'm doing. I think I have other problems in the code as well, but I can't even get past the SQL connection to test the rest. Here is my code:
string svrConnection = "Server=.\\sqlexpress;Database="+db+";User ID=user;Password=password;";
SqlConnection con;
SqlCommand cmd;
Directory.CreateDirectory("C:\\"db"\\");
FileInfo file = new FileInfo("C:\\script.sql");
string PCS = file.OpenText().ReadToEnd();
con = new SqlConnection(svrConnection);
StreamWriter PCSLog = new StreamWriter(#"C:\\" + db + "\\Log" + db + ".txt");
try
{
con.Open();
cmd = new SqlCommand(PCS, con);
cmd.ExecuteNonQuery();
using (SqlDataReader pcsrdr = cmd.ExecuteReader())
using (PCSLog)
{
while (pcsrdr.Read())
PCSLog.WriteLine(pcsrdr[0].ToString() + pcsrdr[1].ToString() + ",");
}
PCSLog.Close();
cmd.Dispose();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection !", ex.Message);
}
There are additional problems with your code:
The Lines
cmd.Dispose();
con.Close();
are not guaranteed to execute if an exception occurs.
You call PCSLog.Close AFTER after you have disposed of it
I would suggest this as a better alternative (irrespective of the other comments made here).
string svrConnection = "Server=.\\sqlexpress;Database="+db+";User ID=user;Password=password;";
Directory.CreateDirectory("C:\\" + db + "\\");
FileInfo file = new FileInfo("C:\\script.sql");
string PCS = file.OpenText().ReadToEnd();
try
{
using (SqlConnection con = new SqlConnection(svrConnection))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(PCS, con))
{
cmd.ExecuteNonQuery();
using (SqlDataReader pcsrdr = cmd.ExecuteReader())
using (StreamWriter PCSLog = new StreamWriter("C:\\" + db + "\\Log" + db + ".txt"))
{
while (pcsrdr.Read())
PCSLog.WriteLine(pcsrdr[0].ToString() + pcsrdr[1].ToString() + ",");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection !", ex.Message);
}
I think the issue is your connection string. Try this:
string svrConnection = "Data Source=.\\SQLEXPRESS;Initial Catalog=" + db + ";User Id=user;Password=password;"
Or to get a connection using your windows credentials:
string svrConnection = "Data Source=.\\SQLEXPRESS;Initial Catalog=" + db + ";Trusted_Connection=True;"
Also, ExecuteNonQuery does not run each command separated by GO. You will need to split your query into sections and run each individually.
I'm trying to retrieve data from database in Microsoft visual studio 2013 . I am totally lost whether I am already able to connect to the database or not and I am not sure how to retrieve data using c# as I am totally new to c#.
I am also not sure where I should put the static void main method statement before or after connectDB() method.
private void connectDB()
{
// server = "172.20.129.159";
database = "eyetracker";
server = "localhost";
// uid = "ogamaaccess";
// password = "ogama";
uid = "root";
password = "root";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
c = new MySqlConnection(connectionString);
Console.WriteLine("Connected to database");
}
private bool OpenConnection()
{
try
{
c.Open();
Console.WriteLine("Connection Opened.");
return true;
}
catch (MySqlException)
{
return false;
}
You need to install the MySql NET Connector that provides the appropriate bits to connect to MySQL database.
After installing the provider you need to add a reference to MySql.Data.Dll and add the appropriate using statement to your code
using MySql.Data.MySqlClient;
You also need to change your connection string which could be found in here.
Connection code should look something close to this:
private void Login() // login method
{
string connectString = #"uid=<UserID>;password=<Password>;
server=<IPorDomainNameOfDatabase>;
database=<DatabaseNameOnServer>;";;
using(MySqlConnection cnn = new MySqlConnection(connectString))
{
try
{
cnn.Open();
}
catch (Exception e)
{
.....
}
}
}
Full code could look something like this (command should be edited according to data you want to retrieve):
MySqlConnection connect = new MySqlConnection(connectString);
MySqlCommand command = connect.CreateCommand();
command.CommandText = "Select <VALUE> from <TABLE> order by <ID> desc limit <0,1>;";
//Command to get query needed value from DataBase
connect.Open();
MySqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
var result = reader.GetString(0);
}
Note: I strongly suggest you to put connect.Open(); into TryCatch statment, since there are many things that can do wrong and your program will crash.
I am having some trouble with my update() method. The idea is that the user Provides a recipe name, ingredients, instructions and then selects an image using Filestream.
Once the user clicks 'Add Recipe' this will call the update method, however as things stand I am getting an error which is mentioning the contents of the text box:
Here is the update() method code:
private void updatedata()
{
// filesteam object to read the image
// full length of image to a byte array
try
{
// try to see if the image has a valid path
if (imagename != "")
{
FileStream fs;
fs = new FileStream(#imagename, FileMode.Open, FileAccess.Read);
// a byte array to read the image
byte[] picbyte = new byte[fs.Length];
fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
//open the database using odp.net and insert the lines
string connstr = #"Server=mypcname\SQLEXPRESS;Database=RecipeOrganiser;Trusted_Connection=True";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
string query;
query = "insert into Recipes(RecipeName,RecipeImage,RecipeIngredients,RecipeInstructions) values (" + textBox1.Text + "," + " #pic" + "," + textBox2.Text + "," + textBox3.Text + ")";
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "pic";
picparameter.Value = picbyte;
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add(picparameter);
cmd.ExecuteNonQuery();
MessageBox.Show("Image successfully saved");
cmd.Dispose();
conn.Close();
conn.Dispose();
Connection();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Can anyone see where I have gone wrong with the insert into Recipes query or suggest an alternative approach to this part of the code?
Your code is open to SQL Injection, but probably your error comes from some text that contains a single quote (the instructions fields for example) and this break your command string build using concatenating the user input.
EDIT
As someone pointed in comment the error is caused by the missing quotes around your textboxes. But while easy to fix that's not the way to go because it is wrong to fix the error adding the missing quotes. It is just postponig the problem leaving a big security hole waiting to be exploited.
A parameterized query could avoid all this mess.
string connstr = "....";
string query = "insert into Recipes(RecipeName,RecipeImage,RecipeIngredients,RecipeInstructions) " +
"values (#name, #pic, #ing, #instr)";
using(SqlConnection conn = new SqlConnection(connstr))
using(SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "#pic";
picparameter.Value = picbyte;
cmd.Parameters.Add(picparameter);
cmd.Parameters.AddWithValue("#name", textbox1.Text);
cmd.Parameters.AddWithValue("#ing", textbox2.Text);
cmd.Parameters.AddWithValue("#instr", textbox3.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Image successfully saved");
}
Since you using string concatenations, you probably missed a quote or you put an extra quote or missed a comma or put extra comma etc etc....
Don't use this way!
Your error doesn't look obviously but you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
query = "insert into Recipes(RecipeName,RecipeImage,RecipeIngredients,RecipeInstructions) values (#p1, #pic, #p3, #p4)";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue(#p1, textBox1.Text);
cmd.Parameters.AddWithValue(#pic, textBox1.Text);
cmd.Parameters.AddWithValue(#p3, textBox1.Text);
cmd.Parameters.AddWithValue(#p4, picparameter);
try this
query = "insert into Recipes(RecipeName,RecipeImage,RecipeIngredients,RecipeInstructions) values ('" + textBox1.Text + "'," + " #pic" + ",'" + textBox2.Text + "','" + textBox3.Text + "')";