Using Database Change Notification on multiple tables - c#

I am developing an application in C# where I'm trying to use Oracle Database Change Notification.
When I'm using DCN for one table, everything is working as expected but when I am trying to use two tables, I get the following error: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt", on the line cmd.ExecuteNonQuery();
Here is the code:
string sql = "select rowid, first_name, last_name, salary from employees where employee_id = :1" +
"select country_id, country_name, region_id from countries where country_id = :2";
string constr = "User Id=hr;Password=Parola_007;Data Source=ORCL;Pooling=false";
con = new OracleConnection(constr);
con.Open();
OracleCommand cmd = new OracleCommand(sql, con);
OracleParameter p_id = new OracleParameter();
p_id.OracleDbType = OracleDbType.Decimal;
p_id.Value = 149;
OracleParameter p_id2 = new OracleParameter();
p_id2.OracleDbType = OracleDbType.Varchar2;
p_id2.Value = "BE";
cmd.BindByName = true;
cmd.Parameters.Add(p_id);
cmd.Parameters.Add(p_id2);
OracleDependency dep = new OracleDependency(cmd);
cmd.Notification.IsNotifiedOnce = false;
dep.OnChange += new OnChangeEventHandler(OnDatabaseNotification);
cmd.ExecuteNonQuery();
public static void OnDatabaseNotification(object src, OracleNotificationEventArgs args)
{
string sql = "select rowid, first_name, last_name, salary from employees where rowid = :1" +
"select rowid, country_id, country_name, region from countries where rowid = :2";
OracleParameter p_rowid = new OracleParameter();
p_rowid.Value = args.Details.Rows[0]["rowid"];
OracleParameter p_rowid2 = new OracleParameter();
p_rowid2.Value = args.Details.Rows[1]["rowid"];
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = sql;
cmd.BindByName = true;
cmd.Parameters.Add(p_rowid);
cmd.Parameters.Add(p_rowid2);
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
Console.WriteLine();
Console.WriteLine("Database Change Notification received!");
DataTable changeDetails = args.Details;
Console.WriteLine("Resource {0} has changed.", changeDetails.Rows[0]["ResourceName"]);
Console.WriteLine("Resource {1} has changed.", changeDetails.Rows[1]["ResourceName"]);
dr.Dispose();
cmd.Dispose();
p_rowid.Dispose();
}
Am I doing something wrong?
Thanks.

1: you cannot do 2 sql in 1 command.
2: You can use the table trigger in oracle to check the changed table data. All changes should be logged in a table and only need to be query from that table.
sorry for my english

Related

Insert into mysql tables

I'm trying to insert some records to 2 tables at same event
private void Btngravar_Click(object sender, EventArgs e)
{
MySqlConnection conn = new MySqlConnection("server=localhost;user id=root;database=saude;Password=");
conn.Open();
MySqlCommand objcmd = new MySqlCommand("insert into dispensacao (DESTINATARIO,COD_UNIDADE,COD_DEPARTAMENTO,DATA,SOLICITANTE,DEFERIDO_POR) values(?,?,?,?,?,?)", conn);
objcmd.Parameters.Add("#DESTINATARIO", MySqlDbType.VarChar, 45).Value = Cmbdestinatario.Text;
objcmd.Parameters.AddWithValue("#COD_UNIDADE", string.IsNullOrEmpty(Txtcodigounidade.Text) ? (object)DBNull.Value : Txtcodigounidade.Text);
objcmd.Parameters.AddWithValue("#COD_DEPARTAMENTO", string.IsNullOrEmpty(Txtcodigodep.Text) ? (object)DBNull.Value : Txtcodigodep.Text);
DateTime fdate = DateTime.Parse(Txtdata.Text);
objcmd.Parameters.Add("#DATA", MySqlDbType.DateTime).Value = fdate;
objcmd.Parameters.Add("#SOLICITANTE", MySqlDbType.VarChar, 45).Value = Txtsolicitante.Text;
objcmd.Parameters.Add("#DEFERIDO_POR", MySqlDbType.VarChar, 45).Value = Txtdeferido.Text;
objcmd.ExecuteNonQuery();
conn.Close();
conn.Open();
objcmd = new MySqlCommand("insert into produtos_disp(COD_DISPENSACAO,COD_PRODUTO,PRODUTO,QUANTIDADE) values (?,?,?,?)", conn);
string selectid = "select ifnull (max(ID),1) from dispensacao";
objcmd = new MySqlCommand(selectid, conn);
MySqlDataReader reader = objcmd.ExecuteReader();
if (reader.Read())
{
Txtcodigo.Text = reader.GetString("ID");
}
//Txtcodigo.DataBindings.Add("Text", dtid, "ID");
objcmd.Parameters.AddWithValue("#COD_DISPENSACAO", Txtcodigo.Text);
objcmd.Parameters.AddWithValue("#COD_PRODUTO", dtproddisp.Rows[0][0]);
objcmd.Parameters.AddWithValue("#PRODUTO", dtproddisp.Rows[0][1]);
objcmd.Parameters.AddWithValue("#PRODUTO", dtproddisp.Rows[0][2]);
Code from the comment
string selectQuery = "SELECT * from departamento";
connection.Open();
MySqlCommand command = new MySqlCommand(selectQuery, connection);
MySqlDataReader reader = command.ExecuteReader();
DataTable dt2 = new DataTable();
dt2.Load(reader);
Cmbdestinatario.DisplayMember = "nome";
Cmbdestinatario.ValueMember = "CODIGO";
Cmbdestinatario.DataSource = dt2;
Txtcodigodep.DataBindings.Add("Text", dt2, "CODIGO");
The first part is working, I can see records inserted on dispensacao table, but the second isn't working, error:
Could not find specified column in results: ID
and I need to get products from datagridview,
App screen:
MySQL Dispensacao table:
My problem now is inserting those selected products from datagridview on database and get the id from dispensacao to insert on products table,
If you want to insert more rows in a database(from what I known), you should add a checkbox in a DataGridView Column and store checked rows to a list. Then you should use a for loop to insert each data to Database by list values.
If you want the code please comment me.

Update table record from sqlcommand

I have this situation: in DataEntryForm I have a dropdownlist, where user selects a letter number, and according to that inserts other related data.
I plan to change letter's status in other table by choosing in dropdownlist automatically.
I am using this code:
SqlParameter answertoparam = new SqlParameter("answerto", ansTo);
string commandText = "update IncomeLetters set IncomeLetters.docState_ID ='2' where income_number=('" + ansTo + "' )";
SqlCommand findincomelett = new SqlCommand(commandText, conn);
comm.Parameters.Add(answertoparam);
conn.Open();
findincomelett.ExecuteNonQuery();
comm.ExecuteNonQuery();
Unfortunately, the result is nothing.
Server is not giving error, and it simply refreshes the page that is it.
In your posted code, you are passing the SqlParameter as well as passing the value as raw data. Do either of one and preferably pass it as SqlParameter like
SqlParameter answertoparam = new SqlParameter("answertoparam", ansTo);
string commandText = "update IncomeLetters set IncomeLetters.docState_ID = '2' where income_number = #answertoparam";
SqlCommand findincomelett = new SqlCommand(commandText, conn);
findincomelett.Parameters.Add(answertoparam);
conn.Open();
findincomelett.ExecuteNonQuery();
Moreover, you have two SqlCommand object in place and calling two ExecuteNonQuery() on them. correct that ... see below
SqlCommand findincomelett = new SqlCommand(commandText, conn); --1
comm.Parameters.Add(answertoparam); --2
conn.Open();
findincomelett.ExecuteNonQuery(); --1
comm.ExecuteNonQuery(); --2
As far as I understand, the issue is that the correct IncomeLetters.docState_ID is not updated to '2'.
You may want to debug and see what value you are getting in :
string ansTo = ddlAnswerTo.SelectedItem.Value;
The record in the database that you are expecting to be updated may not have the record that satisfies the where clause 'income_number = #answertoparam'
I would like to bring you here full code of the page.
Idea is: I have page for enrollment. I am passing data to DB through stored procedure (DataInserter).
Problem is here: during enrollment, user selects from dropdownlist number of the letter he would like to answer to, and in the end, the status of the letter on other table of DB (IncomeLetters.tbl), would change from "pending"('1') to "issued" ('2').
I guess, I could clear my point to you and thank you for your support!
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MaktubhoConnectionString2"].ConnectionString);
using (SqlCommand comm = new SqlCommand("DataInserter", conn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Connection = conn;
SqlParameter employeeparam = new SqlParameter("EmployeeSentIndex", int.Parse(ddlemployee.SelectedItem.Value));
SqlParameter doctypeparam = new SqlParameter("doctype_ID", int.Parse(ddldoctype.SelectedItem.Value));
SqlParameter doccharparam = new SqlParameter("docchar_ID", int.Parse(ddldocchar.SelectedItem.Value));
SqlParameter authorityparam = new SqlParameter("authority", txtauthority.Text);
SqlParameter subjectparam = new SqlParameter("subject", txtsubject.Text);
DateTime dt = DateTime.Now;
string todasdate = dt.ToString("d", CultureInfo.CreateSpecificCulture("de-DE"));
SqlParameter entrydateparam = new SqlParameter("entrydate", todasdate);
string Pathname = "UploadImages/" + Path.GetFileName(FileUpload1.PostedFile.FileName);
SqlParameter imagepathparam = new SqlParameter("image_path", Pathname);
SqlParameter loginparam = new SqlParameter("login", "jsomon");
comm.Parameters.Add(employeeparam);
comm.Parameters.Add(doctypeparam);
comm.Parameters.Add(doccharparam);
comm.Parameters.Add(authorityparam);
comm.Parameters.Add(subjectparam);
comm.Parameters.Add(entrydateparam);
comm.Parameters.Add(imagepathparam);
comm.Parameters.Add(loginparam);
comm.Parameters.Add("#forlabel", SqlDbType.VarChar, 100);
comm.Parameters["#forlabel"].Direction = ParameterDirection.Output;
FileUpload1.SaveAs(Server.MapPath("~/UploadImages/" + FileUpload1.FileName));
string ansTo = ddlAnswerTo.SelectedItem.Value;
SqlParameter answertoparam = new SqlParameter("answertoparam", ansTo);
string commandText = "update IncomeLetters set IncomeLetters.docState_ID = '2' where income_number = #answertoparam";
SqlCommand findincomelett = new SqlCommand(commandText, conn);
findincomelett.Parameters.Add(answertoparam);
conn.Open();
findincomelett.ExecuteNonQuery();
comm.ExecuteNonQuery();
lblresult.Visible = true;
Image1.Visible = true;
lblresult.Text = "Document number:";
lblnumber.Visible = true;
lblnumber.Text = (string)comm.Parameters["#forlabel"].Value; ;
conn.Close();
}
txtauthority.Text = "";
txtsubject.Text = "";
}

DataRoutines not creating data in Access Database

today, I am trying to use DataRoutines to insert some values into my Access Database. However, it did not work as well as there were no records created. Does anyone know what's wrong with my code?
This is my DataRoutines (dataroutines2) file
public void CreateRecs(string strUserId)
{
OleDbConnection mDB = new OleDbConnection();
mDB.ConnectionString = "Provider = Microsoft.ACE.OLEDB.12.0;Data source="
+ Server.MapPath("~/App_Data/webBase.accdb");
OleDbCommand cmd; OleDbDataReader rdr;
string strSql;
string strOFlag = "F";
// check to see if there is an active order record
strSql = "SELECT eStatus FROM enrolInfo WHERE eUserId = #UserId "
+ "ORDER BY eEnrolNo DESC;";
cmd = new OleDbCommand(strSql, mDB);
cmd.Parameters.Add("#UserId", OleDbType.Char).Value = strUserId;
mDB.Open();
rdr = cmd.ExecuteReader();
Boolean booRows = rdr.HasRows;
if (booRows) //when booRows is true, there are order records for the user
{
rdr.Read();
if ((string)rdr["eStatus"] != "Ordering") //status of an active order is "Ordering"
{
strOFlag = "M"; //"T" means there is a need to create a new Orders record
}
else { strOFlag = "M"; }
mDB.Close();
if (strOFlag == "M")
{
//insert a new order record
string strStatus = "Ordering";
strSql = "INSERT INTO enrolInfo (eUserId, eStatus) VALUES (#UserId, #Status)";
cmd = new OleDbCommand(strSql, mDB);
cmd.Parameters.AddWithValue("#UserId", strUserId);
cmd.Parameters.AddWithValue("#Status", strStatus);
mDB.Open();
cmd.ExecuteNonQuery();
mDB.Close();
}
//get back order No - this order no is needed when the user buys an item
strSql = "SELECT eEnrolNo FROM enrolInfo WHERE eUserId = #UserId "
+ "ORDER BY eEnrolNo DESC;";
cmd = new OleDbCommand(strSql, mDB);
cmd.Parameters.Add("#UserId", OleDbType.Char).Value = strUserId;
mDB.Open();
rdr = cmd.ExecuteReader();
rdr.Read();
Session["tOrderNo"] = rdr["eEnrolNo"]; //store the active order no in the sOrderNo
mDB.Close();
return;
}
}
This is the code that will route the solution to the DataRoutines file in my Register Page
//prepare Session variables for newly register customer
Session["sFlag"] = "M";
Session["tUserId"] = (string)txtUserId.Text;
Session["tName"] = (string)txtName.Text;
Session["tAddress"] = (string)txtAddress.Text;
Session["tTel"] = (string)txtTel.Text;
Session["tEmail"] = (string)txtEmail.Text;
String strUserId = (string)Session["tUserId"];
DataRoutines2 DRObject = new DataRoutines2();
DRObject.CreateRecs(strUserId);
Thanks for your help

Read CheckBox Values in ASP.Net from a SQL db?

I have a table of CheckBoxes that are inserted into a SQL db as '1' and '0'. However, I would like to retrieve those values again with a load event, but I'm not able to get them. This is my code:
private void getAuditChecklist()
{
SqlCommand cmd = null;
string conn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string queryString = #"SELECT Mount, Braker, Access, Conn_Net, Log_Book, Pictures, Floor, Cb_Lenght, Channel FROM AUDITOR_CHECKLIST " +
"WHERE SITE_ID = #SiteID";
using (SqlConnection connection =
new SqlConnection(conn))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
cmd = new SqlCommand(queryString);
cmd.Connection = connection;
cmd.Parameters.Add(new SqlParameter("#SiteID", //the name of the parameter to map
System.Data.SqlDbType.NVarChar, //SqlDbType value
20, //The width of the parameter
"SITE_ID")); //The name of the column source
//Fill the parameter with the value retrieved
//from the text field
cmd.Parameters["#SiteID"].Value = foo.Site_ID;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
CheckBox1.Checked = (reader.GetBoolean(reader.GetOrdinal("Mount")));
CheckBox2.Checked = (reader.GetBoolean(reader.GetOrdinal("Braker")));
CheckBox3.Checked = (reader.GetBoolean(reader.GetOrdinal("Access")));
CheckBox4.Checked = (reader.GetBoolean(reader.GetOrdinal("Conn_Net")));
CheckBox5.Checked = (reader.GetBoolean(reader.GetOrdinal("Log_Book")));
CheckBox6.Checked = (reader.GetBoolean(reader.GetOrdinal("Pictures")));
CheckBox8.Checked = (reader.GetBoolean(reader.GetOrdinal("Floor")));
CheckBox9.Checked = (reader.GetBoolean(reader.GetOrdinal("Cb_lenght")));
CheckBox10.Checked = (reader.GetBoolean(reader.GetOrdinal("Channel")));
}
reader.Close();
}
}
What am I missing to get the checkmark from the sql db? Below is how insert into sql:
private void SaveAuditChecklist()
{
if (auditChecklist != null)
{
SqlCommand cmd = null;
string conn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string queryString = #"INSERT INTO AUDITOR_CHECKLIST VALUES(" +
"#SiteID, #Mount, #Braker, #Access, #ConnNet, #LogBook, #Pictures, #Floor, #CbLenght, #Channel) ";
using (SqlConnection connection =
new SqlConnection(conn))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
cmd = new SqlCommand(queryString);
cmd.Connection = connection;
cmd.Parameters.Add(new SqlParameter(
"#SiteID", //the name of the parameter to map
System.Data.SqlDbType.NVarChar, //SqlDbType value
20, //The width of the parameter
"Site_ID")); //The name of the column source
//Fill the parameter with the value retrieved
//from the text field
cmd.Parameters["#SiteID"].Value = foo.Site_ID;
cmd.Parameters.Add(new SqlParameter("#Mount", SqlDbType.Bit));
cmd.Parameters["#Mount"].Value = CheckBox1.Checked;
cmd.Parameters.Add(new SqlParameter("#Braker", SqlDbType.Bit));
cmd.Parameters["#Braker"].Value = CheckBox2.Checked;
cmd.Parameters.Add(new SqlParameter("#Access", SqlDbType.Bit));
cmd.Parameters["#Access"].Value = CheckBox3.Checked;
cmd.Parameters.Add(new SqlParameter("#ConnNet", SqlDbType.Bit));
cmd.Parameters["#ConnNet"].Value = CheckBox4.Checked;
cmd.Parameters.Add(new SqlParameter("#LogBook", SqlDbType.Bit));
cmd.Parameters["#LogBook"].Value = CheckBox5.Checked;
cmd.Parameters.Add(new SqlParameter("#Pictures", SqlDbType.Bit));
cmd.Parameters["#Pictures"].Value = CheckBox6.Checked;
cmd.Parameters.Add(new SqlParameter("#Floor", SqlDbType.Bit));
cmd.Parameters["#Floor"].Value = CheckBox8.Checked;
cmd.Parameters.Add(new SqlParameter("#CbLenght", SqlDbType.Bit));
cmd.Parameters["#CbLenght"].Value = CheckBox9.Checked;
cmd.Parameters.Add(new SqlParameter("#Channel", SqlDbType.Bit));
cmd.Parameters["#Channel"].Value = CheckBox10.Checked;
cmd.ExecuteReader();
}
}
}
Booleans are stored as 1 or 0 in Sql Database, but the datareader do the conversion for you. Instead use:
var myBool = reader.GetBoolean(i);
Then just assign the value to the control's value property.
Finally got the reader they way it should work to get the checkmark values. I edited my question with the working code; however, below is what I added or changed for the reader:
while (reader.Read())
{
CheckBox1.Checked = (reader.GetBoolean(reader.GetOrdinal("Mount")));
CheckBox2.Checked = (reader.GetBoolean(reader.GetOrdinal("Braker")));
CheckBox3.Checked = (reader.GetBoolean(reader.GetOrdinal("Access")));
CheckBox4.Checked = (reader.GetBoolean(reader.GetOrdinal("Conn_Net")));
CheckBox5.Checked = (reader.GetBoolean(reader.GetOrdinal("Log_Book")));
CheckBox6.Checked = (reader.GetBoolean(reader.GetOrdinal("Pictures")));
CheckBox8.Checked = (reader.GetBoolean(reader.GetOrdinal("Floor")));
CheckBox9.Checked = (reader.GetBoolean(reader.GetOrdinal("Cb_lenght")));
CheckBox10.Checked = (reader.GetBoolean(reader.GetOrdinal("Channel")));
}

How to get a value in another table, store it in a variable or data reader, and then use it to update another table

does anyone know how do I get the StudentID from Students table, store it in datareader or dataset, and then use it to update another table, which is Users Table, because I want the username and password of users would be their StudentID as a default. BTW, this is C# ASP.NET.
Here is my code.
SqlConnection conUpdate = new SqlConnection(GetConnectionString());
conUpdate.Open();
SqlCommand com2 = new SqlCommand();
com2.Connection = conUpdate;
com2.CommandText = "SELECT Students.StudentID, Users.UserID FROM Students, Users " +
"WHERE Students.UserID = Users.UserID";
int UserId = ((int)com2.ExecuteScalar());
com2.CommandText = "SELECT MAX(StudentID) FROM Students";
int StudentId = ((int)com2.ExecuteScalar());
com2.CommandType = CommandType.Text;
com2.CommandText = "UPDATE Users SET UserName=#UserName, Password=#Password WHERE UserID=#UserID";
com2.Parameters.Add("#UserName", SqlDbType.NVarChar);
com2.Parameters.Add("#Password", SqlDbType.NVarChar);
com2.Parameters[0].Value = reader;
com2.Parameters[1].Value = reader;
com2.ExecuteNonQuery();
conUpdate.Close();
conUpdate.Dispose();
Since you already getting UserId in your select query, you should get the value using DataReader. like this:
// Execute the query
SqlDataReader rdr = cmd.ExecuteReader();
int UserId;
while(rdr.Read())
{
UserId = Convert.ToInt32(rdr["UserID"].ToString());
}
Your command com2.CommandText = "SELECT MAX(StudentID) FROM Students"; will return the Max student ID, and that is probably not needed. Your earlier command com2.CommandText = "SELECT Students.StudentID, Users.UserID .... is what you need to get the student UserID.
You can use Data reader (Connection oriented) like below:
SqlDataReader reader = com2.ExecuteReader();
while (reader.Read())
{
int UserId = Convert.ToInt(reader[0]);// or reader["UserID"]
}
reader.Close();
Or you can use DataAdapter (disconnected mode) like:
SqlDataAdapter a = new SqlDataAdapter(com2, connection);
DataTable dt = new DataTable();
a.Fill(dt);
Now your dt.Rows["UserID"] will have the UserID you need.
You may wanna see this: http://www.dotnetperls.com/sqldataadapter
If I understood you correctly, I think the following code might work. Or in the least give you an idea about how you can go about it. Am assuming that you want each student's UserName and Password to default to their StudentID
SqlConnection conUpdate = new SqlConnection(GetConnectionString());
conUpdate.Open();
SqlCommand com2 = new SqlCommand();
com2.Connection = conUpdate;
com2.CommandType = CommandType.Text;
com2.CommandText = "SELECT Students.StudentID, Users.UserID FROM Students, Users " +
"WHERE Students.UserID = Users.UserID";
SqlDataReader reader = com2.ExecuteReader();
if(reader != null)
{
while(reader.Read())
{
SqlCommand com3 = new SqlCommand();
com3.Connection = conUpdate;
com3.CommandType = CommandType.Text;
com3.CommandText = "UPDATE Users SET UserName=#UserName, Password=#Password WHERE UserID=#UserID";
// Assuming that you need both the UserName and Password to default to StudentID
com3.Parameters.AddWithValue("#UserName", reader.GetString(0)); // Assuming StudentID is NVARCHAR
com3.Parameters.AddWithValue("#Password", reader.GetString(0)); // Assuming StudentID is NVARCHAR
com3.Parameters.AddWithValue("#UserID", reader.GetString(1)); // Assuming UserID is NVARCHAR
com3.ExecuteNonQuery();
}
reader.Close();
}
conUpdate.Close();

Categories