I am using this code in c# to update my table:
public static int updateMytable(string accessCode, string response)
{
OracleConnection conn = DB.GetConnection();
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "update mytable set response_id= :p_response , response_date=sysdate where access_code = :p_access_code";
cmd.Parameters.Add("p_access_code", accessCode);
cmd.Parameters.Add("p_response", response);
cmd.CommandType = CommandType.Text;
int res = cmd.ExecuteNonQuery();
conn.Close();
return res;
}
access_code is varchar2
When I remove the condition "where" It updates everything.
When I use a string command instead of bind variables it works fine too.
string str = "update mytable set response_id= "+response+" , response_date=sysdate where access_code = "+accessCode;
Could you advise?
Add cmd.BindByName = true; in order to bind variables (:p_response, :p_access_code) by their names, not positions:
public static int updateMytable(string accessCode, string response) {
if (string.IsNullOrEmpty(accessCode))
return 0;
using (OracleConnection conn = DB.GetConnection()) {
conn.Open();
using (OracleCommand cmd = new OracleCommand()) {
// When binding varaibles, use their names, not positions
cmd.BindByName = true;
cmd.Connection = conn;
cmd.CommandText =
#"update mytable
set response_id = :p_response,
response_date = sysdate
where access_code = :p_access_code";
cmd.Parameters.Add(":p_response", OracleDbType.Varchar2);
cmd.Parameters.Add(":p_access_code", OracleDbType.Varchar2);
cmd.Parameters[":p_response"].Value = string.IsNullOrEmpty(response)
? (object) (DBNull.Value)
: response;
cmd.Parameters[":p_access_code"].Value = accessCode;
return cmd.ExecuteNonQuery();
}
}
}
Related
It's my function to add to a table:
public int insertHistory(string title, string description, int isDone, int userId)
{
int s = -1;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "INSERT INTO History(title,description,isDone,userId) VALUES(#param1,#param2,#param3,#param4)";
using (SqlCommand cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.Add("#param1", SqlDbType.NVarChar, 10).Value = title;
cmd.Parameters.Add("#param2", SqlDbType.NVarChar, 400).Value = description;
cmd.Parameters.Add("#param3", SqlDbType.Int).Value = isDone;
cmd.Parameters.Add("#param4", SqlDbType.Int).Value = userId;
cmd.CommandType = CommandType.Text;
s = cmd.ExecuteNonQuery();
}
}
return s;
}
What code do I need to write to remove from the table by title or something?
You have asked to delete using Title and here is how to do it
public int deleteHistory(string title)
{
int s = -1;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "DELETE FROM History WHERE Title = #title)";
using (SqlCommand cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.Add("#title", SqlDbType.NVarChar, 10).Value = title;
s = cmd.ExecuteNonQuery();
}
}
return s
}
However in this way you could end to delete more records than you want. If two or more records have the same title you will delete all records with the same title. You could mitigate this problem adding also the UserID to the where condition and the relative parameter to the parameters collection.
"DELETE FROM History WHERE Title = #title AND UserID = #uid"
So you delete only titles of a specific user, but still this is not safe. If your table has an IDENTITY column and you retrieve the values from that column when you read the records then you can pass that unique value to your query and delete specifically only one record.
"DELETE FROM History WHERE HistoryID = #hid"
as you are using SqlConnection and a plain SQL statement. You need to call a Delete statement in your code:
public void DeleteHistory(string title)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "delete from History where title= #title";
using (SqlCommand cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.Add("#title", SqlDbType.NVarChar).Value = title;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
}
I am attempting to create a simple news and image system, I first need to use SCOPE_IDENTITY() and execute scalar, but I'm not having much luck. I get a:
The name 'newID' does not exist in the current context
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUpload1.PostedFile != null)
{
string FileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
//Save files to disk
FileUpload1.SaveAs(Server.MapPath("/images/admin/news/" + FileName));
//Add Entry to DataBase
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
int newID = 0;
string strQuery = #"insert into tblFiles (FileName, FilePath) values(#FileName, #FilePath); select cast(scope_identity() As int);";
using (SqlConnection connection = new SqlConnection(strConnString))
using (SqlCommand command = new SqlCommand(strQuery, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("#FileName", SqlDbType.VarChar).Value = FileName;
command.Parameters.Add("#FilePath", SqlDbType.VarChar).Value = "/images/admin/news/" + FileName;
try
{
connection.Open();
newID = (int)command.ExecuteScalar();
}
catch
{
}
}
}
if (newID > 0)
{
string strAddNewsQuery = #"insert into tblNews (newsTitle, newsDate, newsSummary, newsContent, newsPicID)
values(#newsTitle, #newsDate, #newsSummary, #newsContent, #newsPicID)";
using (SqlConnection connection = new SqlConnection(strConnString))
using (SqlCommand command = new SqlCommand(strAddNewsQuery, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("#newsTitle", SqlDbType.VarChar).Value = FileName;
command.Parameters.AddWithValue("#newsDate", txtnewsdate.Text);
command.Parameters.AddWithValue("#newsSummary", txtnewssummary.Text);
command.Parameters.AddWithValue("#newsContent", txtnewsmaincontent.Text);
command.Parameters.Add("#newsPicID", SqlDbType.Int).Value = newID;
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch
{
}
finally {
connection.Close();
connection.Dispose();
}
}
}
}
}
An int does not have properties you can access. Change
command.Parameters.AddWithValue("#newsPicID", newID.Value);
into
command.Parameters.AddWithValue("#newsPicID", newID);
Even better is to use parameters with the database value type specified.
command.Parameters.Add("#newsPicID", SqlDbType.Int).Value = newID;
But you are trying to get the SCOPE_IDENTITY() of table tblNews, not from tblFiles to be used in tblNews as newsPicID. You need to get SCOPE_IDENTITY() from the first database command.
UPDATE
And you need to assign the connection to the command.
SqlCommand cmd = new SqlCommand(strQuery, con)
UPDATE 2
Here is a complete snippet to get you started. Notice the wrapping with using. This ensures proper disposal of connections.
int newID = 0;
using (SqlConnection connection = new SqlConnection(strConnString))
using (SqlCommand command = new SqlCommand(strQuery, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("#FileName", SqlDbType.VarChar).Value = FileName;
command.Parameters.Add("#FilePath", SqlDbType.VarChar).Value = "/images/admin/news/" + FileName;
try
{
connection.Open();
newID = (int)command.ExecuteScalar();
}
catch
{
}
}
if (newID > 0)
{
using (SqlConnection connection = new SqlConnection(strConnString))
using (SqlCommand command = new SqlCommand(strAddNewsQuery, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("#newsTitle", SqlDbType.VarChar).Value = FileName;
//etc
command.Parameters.Add("#newsPicID", SqlDbType.Int).Value = newID;
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch
{
}
}
}
How do I go about setting a MySQL query and parameters based on a condition?
I want different queries based on 'questionSource' as shown below.
However, in my code below, 'cmd' does not exist in the current context.
Alternatively, I could have two different functions for each condition and call the necessary function as required but I imagine there must be a way to have conditions within a connection.
//validation checks
else
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
string questionSource = Session["QuestionSource"].ToString();
string cmdText = "";
if (questionSource.Equals("S"))
{
cmdText += #"SELECT COUNT(*) FROM questions Q
JOIN users U
ON Q.author_id=U.user_id
WHERE approved='Y'
AND role=1
AND module_id=#ModuleID";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = Convert.ToInt32(Session["TestModuleID"]);
}
else if (questionSource.Equals("U"))
{
cmdText += "SELECT COUNT(*) FROM questions WHERE approved='Y' AND module_id=#ModuleID AND author_id=#AuthorID;";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = Convert.ToInt32(Session["TestModuleID"]);
cmd.Parameters.Add("#AuthorID", MySqlDbType.Int32);
cmd.Parameters["#AuthorID"].Value = Convert.ToInt32(Session["UserID"]);
}
int noOfQuestionsAvailable = 0;
int noOfQuestionsWanted = Convert.ToInt32(ddlNoOfQuestions.SelectedValue);
try
{
conn.Open();
noOfQuestionsAvailable = Convert.ToInt32(cmd.ExecuteScalar());
if (noOfQuestionsAvailable < noOfQuestionsWanted)
{
lblError.Text = "There are not enough questions available to create a test.";
}
else
{
Session["TestName"] = txtName.Text;
Session["NoOfQuestions"] = ddlNoOfQuestions.SelectedValue;
Session["QuestionSource"] = rblQuestionSource.SelectedValue;
Session["TestModuleID"] = ddlModules.SelectedValue;
Response.Redirect("~/create_test_b.aspx");
}
}
catch
{
lblError.Text = "Database connection error - failed to get module details.";
}
finally
{
conn.Close();
}
}
declare cmd before if
MySqlCommand cmd = new MySqlCommand("",connStr);
and in each part of if
cmd.CommandText=cmdText;
other suggestion: add
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = Convert.ToInt32(Session["TestModuleID"]);
always before if because it is used in the same way in if and else part
You just have to move the declaration of the cmd outside the if block:
//validation checks
else
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
string questionSource = Session["QuestionSource"].ToString();
string cmdText = "";
MySqlCommand cmd; // <-- here
if (questionSource.Equals("S"))
{
cmdText += #"SELECT COUNT(*) FROM questions Q
JOIN users U
ON Q.author_id=U.user_id
WHERE approved='Y'
AND role=1
AND module_id=#ModuleID";
cmd = new MySqlCommand(cmdText, conn); // remove MySqlCommand here
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = Convert.ToInt32(Session["TestModuleID"]);
}
else if (questionSource.Equals("U"))
{
cmdText += "SELECT COUNT(*) FROM questions WHERE approved='Y' AND module_id=#ModuleID AND author_id=#AuthorID;";
cmd = new MySqlCommand(cmdText, conn); // remove MySqlCommand here
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = Convert.ToInt32(Session["TestModuleID"]);
cmd.Parameters.Add("#AuthorID", MySqlDbType.Int32);
cmd.Parameters["#AuthorID"].Value = Convert.ToInt32(Session["UserID"]);
}
int noOfQuestionsAvailable = 0;
int noOfQuestionsWanted = Convert.ToInt32(ddlNoOfQuestions.SelectedValue);
try
{
conn.Open();
noOfQuestionsAvailable = Convert.ToInt32(cmd.ExecuteScalar());
if (noOfQuestionsAvailable < noOfQuestionsWanted)
{
lblError.Text = "There are not enough questions available to create a test.";
}
else
{
Session["TestName"] = txtName.Text;
Session["NoOfQuestions"] = ddlNoOfQuestions.SelectedValue;
Session["QuestionSource"] = rblQuestionSource.SelectedValue;
Session["TestModuleID"] = ddlModules.SelectedValue;
Response.Redirect("~/create_test_b.aspx");
}
}
catch
{
lblError.Text = "Database connection error - failed to get module details.";
}
finally
{
conn.Close();
}
}
Just move the declaration of the MySqlCommand outside the if/else blocks so you could use it in the final try where you execute the command
//validation checks
else
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using(MySqlConnection conn = new MySqlConnection(connStr))
using(MySqlCommand cmd = conn.CreateCommand())
{
// Don't need to associate the command to the connection
// Already done by the CreateCommand above, just need to set
// the parameters and the command text
if (questionSource.Equals("S"))
{
cmdText = #"....."
cmd.CommandText = cmdText;
....
}
else if (questionSource.Equals("U"))
{
cmdText = "........."
cmd.CommandText = cmdText;
....
}
try
{
conn.Open();
noOfQuestionsAvailable = Convert.ToInt32(cmd.ExecuteScalar());
....
}
}
}
Notice also that you should use the using statement to be sure that your connection and your command are propertly closed and disposed.
I've been trawling through pages and pages on the internet for days now trying different approaches and I'm still not sure how I should be doing this.
On my third InsertCommand, I'd like to reference a column on the other 2 tables.
// Populate a DataSet from multiple Tables... Works fine
sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = new SqlCommand("SELECT * FROM hardware", sqlConn);
sqlDA.Fill(ds, "Hardware");
sqlDA.SelectCommand.CommandText = "SELECT * FROM software";
sqlDA.Fill(ds, "Software");
sqlDA.SelectCommand.CommandText = "SELECT * FROM join_hardware_software";
sqlDA.Fill(ds, "HS Join");
// After DataSet has been changed, perform an Insert on relevant tables...
updatedDs = ds.GetChanges();
SqlCommand DAInsertCommand = new SqlCommand();
DAInsertCommand.CommandText = "INSERT INTO hardware (host, model, serial) VALUES (#host, #model, #serial)";
DAInsertCommand.Parameters.AddWithValue("#host", null).SourceColumn = "host";
DAInsertCommand.Parameters.AddWithValue("#model", null).SourceColumn = "model";
DAInsertCommand.Parameters.AddWithValue("#serial", null).SourceColumn = "serial";
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "Hardware"); // Works Fine
DAInsertCommand.Parameters.Clear(); // Clear parameters set above
DAInsertCommand.CommandText = "INSERT INTO software (description) VALUES (#software)";
DAInsertCommand.Parameters.AddWithValue("#software", null).SourceColumn = "description";
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "Software"); // Works Fine
DAInsertCommand.Parameters.Clear(); // Clear parameters set above
DAInsertCommand.CommandText = "INSERT INTO join_hardware_software (hardware_id, software_id) VALUES (#hardware_id, #software_id)";
// *****
DAInsertCommand.Parameters.AddWithValue("#hardware_id", null).SourceColumn = "?"; // I want to set this to be set to my 'hardware' table to the 'id' column.
DAInsertCommand.Parameters.AddWithValue("#software_id", null).SourceColumn = "?"; // I want to set this to be set to my 'software' table to the 'id' column.
// *****
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "HS Join");
Could somebody please tell me where I am going wrong and how I could potentially overcome this? Many thanks! :)
With regards to your comments this seems to be one of those occasions where if you and I were sat next to each other we'd get this sorted but it's a bit tricky.
This is code I've used when working with SqlConnection and SqlCommand. There might be stuff here that would help you.
public static void RunSqlCommandText(string connectionString, string commandText) {
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand comm = conn.CreateCommand();
try {
comm.CommandType = CommandType.Text;
comm.CommandText = commandText;
comm.Connection = conn;
conn.Open();
comm.ExecuteNonQuery();
} catch (Exception ex) {
System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
el.Source = "data access class";
el.WriteEntry(ex.Message + ex.StackTrace + " SQL '" + commandText + "'");
} finally {
conn.Close();
comm.Dispose();
}
}
public static int RunSqlAndReturnId(string connectionString, string commandText) {
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand comm = conn.CreateCommand();
int id = -1;
try {
comm.CommandType = CommandType.Text;
comm.CommandText = commandText;
comm.Connection = conn;
conn.Open();
var returnvalue = comm.ExecuteScalar();
if (returnvalue != null) {
id = (int)returnvalue;
}
} catch (Exception ex) {
System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
el.Source = "data access class";
el.WriteEntry(ex.Message + ex.StackTrace + " SQL '" + commandText + "'");
} finally {
conn.Close();
comm.Dispose();
}
return id;
}
Can anybody give an example for executing a T-SQL statement using C#?
Do you mean something like this:
private static void ReadOrderData(string connectionString)
{
string commandText = "SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
}
}
}
Or, perhaps something like:
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;
}
Source: MSDN
I suggest that you start with an ADO.NET turorial like this one
http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson01.aspx
How to use SQLCommand
http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson03.aspx
Using a reader:
SqlConnection MSSQLConn = new SqlConnection("your connection string");
MSSQLConn.Open();
SqlCommand MSSQLSelectConsignment = new SqlCommand();
MSSQLSelectConsignment.CommandText = "select * from yourtable where blah = #blah";
MSSQLSelectConsignment.Parameters.AddWithValue("#blah", somestring);
MSSQLSelectConsignment.Connection = MSSQLConnOLD;
SqlDataReader reader = MSSQLSelectConsignment.ExecuteReader();
while (reader.Read())
{
...
}
To bring back a single value:
MSSQLSelectConsignment.CommandText = "select fieldname from yourtable where blah = #blah";
string yourstring = MSSQLSelectConsignment.ExecuteScalar().ToString();
or to bring back number of rows affected for updates etc:
MSSQLSelectConsignment.CommandText = "update yourtable set yourfield = 0 where blah = #blah";
int yourint = MSSQLSelectConsignment.ExecuteNonQuery();
Hope helps :)