I have been trying to insert data into a sql database for the last hours. for one or other reason I am able to connect to the database, but no data is inserted into the database. if I run the sql statement directly in the database it does seem to work. So therefore, I was able to conclude that the statement is correct. Furthermore, there were no errors in runtime. I have got the following c# code:
//Neither of these statements seem to work.
string sqlStatement = "INSERT INTO dbo.eventTable (colA, colB, colC, colD, colE, colF, colG, colH, colI) VALUES (#a,#b,#c,#d,#e,#f,#g,#h,#i)";
string altSqlStatement = "INSERT INTO dbo.eventTable (colA, colB, colC, colD, colE, colF, colG, colH, colI) VALUES (#a,#b,#c,#d,#e,#f,#g,#h,#i)";
foreach (DataRow row in importData.Rows)
{
using (SqlConnection conn = new SqlConnection(form1.Properties.Settings.Default.showConnectionString))
{
using (SqlCommand insertCommand = new SqlCommand())
{
insertCommand.Connection = conn;
insertCommand.CommandText = sqlStatement;
insertCommand.CommandType = CommandType.Text;
insertCommand.Parameters.AddWithValue("#a", row["CUE"].ToString());
insertCommand.Parameters.AddWithValue("#b", row["HH"].ToString());
insertCommand.Parameters.AddWithValue("#c", row["MM"].ToString());
insertCommand.Parameters.AddWithValue("#d", row["SS"].ToString());
insertCommand.Parameters.AddWithValue("#e", row["FF"].ToString());
insertCommand.Parameters.AddWithValue("#f", row["ADDR"].ToString());
insertCommand.Parameters.AddWithValue("#g", row["Event Description"].ToString());
insertCommand.Parameters.AddWithValue("#h", row["CAL"].ToString());
insertCommand.Parameters.AddWithValue("#i", row["PFT"].ToString());
try
{
conn.Open();
int _affected = insertCommand.ExecuteNonQuery();
}
catch(SqlException e)
{
// do something with the exception
}
}
}
}
if I change the connection parameters to something false, an error occurs, so that seems correct.
Any help would be greatly appreciated.
Thanks!
Alex
Try using this function as a template, big difference is that it is opening the connection before creating the command. I've not seen it done the way you have it setup. You also really should be opening the connection outside of the for loop, not in the for loop. Why open and close it repeatedly; the foreach should be inside the inner 'using'
public void ExecuteQuery(string query, Dictionary<string, object> parameters)
{
using (SqlConnection conn = new SqlConnection(this.connectionString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = query;
if (parameters != null)
{
foreach (string parameter in parameters.Keys)
{
cmd.Parameters.AddWithValue(parameter, parameters[parameter]);
}
}
cmd.ExecuteNonQuery();
}
}
}
Related
Context: I'm developing an app for windows in Visual Studio that has a table of stock materials and another of buyed materials, both in a Sql Server.
I want that every time you buy something it is added into the stock table.
I'm new in using SQL with c# combined.
I'm trying this from a tutorial, but does nothing. Not even an exception.
string cmdString = "Insert INTO Table1 (Column_name) VALUES (#val1)";
string connString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True";
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = conn.CreateCommand())
{
comm.Connection = conn;
comm.CommandText = cmdString;
comm.Parameters.AddWithValue("#val1", Value);
try
{
conn.Open();
comm.ExecuteNonQuery();
conn.Close()
}
catch(SqlException ex)
{
}
}
}
Is this totally wrong or should i change something?
Edit: I figured out. I was inserting val1 in a column, but the ID was empty so it throws an NullId exception. For some reason in debug mode I wasn't able to see it.
Thanks for the help. If I have the Table1 with autoincrement why it needs an ID? There is a way that when something is inserted the Id generates automatically?
You can use this query to insert data like that :
{
if (con.State == ConnectionState.Open)
con.Close();
}
{
SqlCommand cmd0561 = new SqlCommand(#"insert into Table1 (value1,value1) values
(#value1,#timee)", con);
cmd0561.Parameters.AddWithValue("#value1", value1.Text.Trim);
cmd0561.Parameters.AddWithValue("#value2", value2.Text.Trim);
con.Open();
cmd0561.ExecuteNonQuery();
con.Close();
}
The first SQL is executing but the second one doesn't seem to work.
When i change the query to the first one it works just fine but when I put it like that it doesn't seem to work for some reason.
I've just started learning MySQL i'm really struggling with this one and understanding the language.
//Classic One that checks if the hwid is there
public void checkHWID(string HWID)
{
string line;
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE HWID = #HWID", con))
{
cmd.Parameters.AddWithValue("#HWID", HWID);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
line = reader[1].ToString();
Console.Write(line);
con.Close();
}
else
{
updateHWID(HWID);
}
}
}
}
}
//This one doesn't seem to update the hwid but when i change the query to the first one it works just fine
public void updateHWID(String HWID)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("INSERT INTO USERS(hwid) VALUES(#HWID)", connection))
{
command.Parameters.AddWithValue("#HWID", HWID);
connection.Close();
}
}
}
Your SQL statement in the updateHWID function isn't working primarily because it is missing the code that executes the command you created.
connection.Open();
using (SqlCommand command = new SqlCommand("INSERT INTO USERS(hwid) VALUES(#HWID)", connection))
{
command.Parameters.AddWithValue("#HWID", HWID);
command.ExecuteNonQuery(); // ADD THIS LINE
}
connection.Close();
Then assuming your table only requires the hwid and no other columns then this could work. If your table has other columns that don't allow nulls then you may get an error for the missing column values.
I use Visual Studio community 2015 and i use MySQL connector (MySQL for Visual Studio) for connection my MySQL database to Visual Studio, this part is already done and i have Visual Studio connected to database.
Now i like to know what is my next step to get (using a select query) data from the database to my form program ?
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;
namespace Test_1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// How can i get data from the database in here ?
}
}
}
I got my answer ! Check best answer.
I've gotta run for a bit so I'll take you at yoyur word that you've tried something and post this in hopes it may help you (it's nice to see what you've done to know how to help you).
You said you had the connection working. Here's some examples of basic queries. The most important thing to remember is there's a lot of different ways to do this, so these are just intended as examples. They are all manual -- for help databinding omething automatically, you'll have to post and ask.
Please PLEASE as you learn to do this - make SURE you always use parameters and don't do things like "UPDATE myUserData set DRIVER_LICENSE = 'U7439821' WHERE LAST_NAME = 'Smith'". You are begging for bad things to happen to you if you do that. Take the extra 30 seconds to use command.Parameter.Add(,).
Finally, these examples are for MS-SQL Server. You'll need to change the connection from SqlConnection to MySqlConnection and from SQLCommand to MySqlCommand.
If you have any other questions, just ask.
//these are connection methods that help connect you to your database manually.
public SqlConnection getConn()
{
return new SqlConnection(getConnString());
}
public string getConnString()
{
return #"Data Source=lily.arvixe.com;Initial Catalog={My_Database_Name};Persist Security Info=True;User ID={My_Database_Username};Password={My_Database_Password};Connection Timeout=7000";
}
//to get a single value from a single field:
public object scalar(string sql)
{
object ret;
using (SqlConnection conn = getConn())
{
conn.Open();
using (SqlCommand com = conn.CreateCommand())
{
com.CommandText = sql;
ret = com.ExecuteScalar();
}
conn.Close();
}
return ret;
}
//To do a SELECT with multiple rows returned
private List<string> get_Column_Names(string tableName)
{
List<string> ret = new List<string>();
using (SqlConnection conn = getConn())
{
conn.Open();
using(SqlCommand com = conn.CreateCommand())
{
com.CommandText = "select column_Name from INFORMATION_SCHEMA.COLUMNS where table_Name = '" + tableName + "'";
com.CommandTimeout = 600;
SqlDataReader read = com.ExecuteReader();
while (read.Read())
{
ret.Add(Convert.ToString(read[0]));
}
}
conn.Close();
}
return ret;
}
// to do an INSERT or UPDATE or anything that does not return data
// USE PARAMETERS if people go anywhere near this data
public void nonQuery(string sql)
{
using(SqlConnection conn = getConn())
{
conn.Open();
using(SqlCommand com = conn.CreateCommand())
{
com.CommandText = sql;
com.CommandTimeout = 5900;
com.ExecuteNonQuery();
}
conn.Close();
}
}
//to save a DataTable manually:
public void saveDataTable(string tableName, DataTable table)
{
using (SqlConnection conn = getConn())
{
conn.Open();
using (var bulkCopy = new SqlBulkCopy(conn))//, SqlBulkCopyOptions.KeepIdentity))
{
// my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings
foreach (DataColumn col in table.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, "[" + col.ColumnName + "]");
}
bulkCopy.BulkCopyTimeout = 8000;
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = 10000;
bulkCopy.EnableStreaming = true;
// bulkCopy.SqlRowsCopied += BulkCopy_SqlRowsCopied;
//bulkCopy.NotifyAfter = 10000;
//isCopyInProgess = true;
bulkCopy.WriteToServer(table);
}
conn.Close();
}
}
Again, there are more than a few ways to accomplish each of these tasks programatically - I'm just showing you the most basic. If you want to learn how to automatically bind a control to data, try searching for "C-sharp Databind CONTROL_NAME Visual studio" and you should get all the help you need.
I got my answer :
MySqlConnection sqlConnection1 = new MySqlConnection("server=server;uid=username;" + "pwd=password;database=database;");
MySqlCommand cmd = new MySqlCommand();
MySqlDataReader reader;
cmd.CommandText = "SELECT * FROM table";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
try
{
reader.Read();
value = reader.GetString(x);
}
finally
{
reader.Close();
}
i'm having an issue using C# inserting multiple rows into a MySQL database, have the following code;
//Upload to mysql
string connStr = "server=server;user=username;database=databasae;port=3306;password=password;";
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
foreach (Channel chan in results)
{
// Perform databse operations
try
{
//Create sql statment with parameters
string sql = "INSERT INTO channels(ID, Name) VALUES (#id,#name)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#id", chan.ID);
cmd.Parameters.AddWithValue("#name", chan.Name);
cmd.ExecuteNonQuery();
updateStatus("Inserted");
}
catch (Exception ex)
{
updateStatus(ex.Message.ToString());
}
conn.Close();
I seem to be getting "connection must be valid and open". From what i can see i'm passing the connection string correctly and i'm using ExecuteNonQuery. And idea's?
thanks
conn.Close(); should be outside the foreach.
The following would work :
//Upload to mysql
string connStr = "server=server;user=username;database=databasae;port=3306;password=password;";
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
foreach (Channel chan in results)
{
// Perform databse operations
try
{
//Create sql statment with parameters
string sql = "INSERT INTO channels(ID, Name) VALUES (#id,#name)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#id", chan.ID);
cmd.Parameters.AddWithValue("#name", chan.Name);
cmd.ExecuteNonQuery();
updateStatus("Inserted");
}
catch (Exception ex)
{
updateStatus(ex.Message.ToString());
}
}
conn.Close();
Looks like the connection is inside the foreach loop. It should be outside the foreach loop.
conn.Close(); should be outside the foreach loop.
How about using
using(MySqlConnection conn = new MySqlConnection(connStr))
{
//your stuff in here
}
This is transformed into a try final block .. so should take care of your connection woes.
add finally block to the try catch code and put conn.close() in it.like
finally
{
if(conn.ConnectionSTate=Connectionstate.open)
{
conn.close()
}
}
In some programming contexts getting a scalar value from a sql query is easy:
RowCount = Connection.Execute("SELECT Count(*) FROM TableA").Fields(0).Value
In C#, given a SqlConnection variable conn that is already open, is there a simpler way to do this same thing without laboriously creating a SqlCommand, a DataReader, and all in all taking about 5 lines to do the job?
SqlCommand has an ExecuteScalar method that does what you want.
cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
Int32 count = (Int32) cmd.ExecuteScalar();
If you can use LINQ2SQL (or EntityFramework) you can simplify the actual query asking to
using (var context = new MyDbContext("connectionString"))
{
var rowCount = context.TableAs.Count();
}
If LINQ2SQL is an option that has lots of other benefits too compared to manually creating all SqlCommands, etc.
There is ExecuteScalar which saves you at least from the DataReader:
static public int AddProductCategory(string newName, string connString)
{
Int32 newProdID = 0;
string sql =
"INSERT INTO Production.ProductCategory (Name) VALUES (#Name); "
+ "SELECT CAST(scope_identity() AS int)";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name", SqlDbType.VarChar);
cmd.Parameters["#name"].Value = newName;
try
{
conn.Open();
newProdID = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return (int)newProdID;
}
(Example taken from this MSDN documentation article)
You do not need a DataReader. This example pulls back the scalar value:
Object result;
using (SqlConnection con = new SqlConnection(ConnectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand(SQLStoredProcName, con)) {
result = cmd.ExecuteScalar();
}
}
Investigate Command.ExecuteScalar:
using(var connection = new SqlConnection(myConnectionString))
{
connection.Open();
using(var command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = mySql;
var result = (int)command.ExecuteScalar();
}
}
If you're feeling really lazy, encapsulate it all in an extension method, like we do.
EDIT: As requested, an extension method:
public static T ExecuteScalar<T> (this SqlConnection connection, string sql)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (string.IsNullOrEmpty(sql))
{
throw new ArgumentNullException("sql");
}
using(var command = connection.CreateCommand())
{
command.CommandText = sql;
command.CommandType = CommandType.Text;
return (T)command.ExecuteScalar();
}
}
Note, this version assumes you've properly built the SQL beforehand. I'd probably create a separate overload of this extension method that took two parameters: the stored procedure name and a List. That way, you could protect yourself against unwanted SQL injection attacks.