Problem in updating database with relationship one to many - sql

I'm trying to update my database but I'm getting this error:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Data.OleDb.OleDbException: You cannot add or change a record because a related record is required in table 'ItemTypes'.
I'm not sure how to fix it.
I don't know what i need to show so I will just show most of everything.
I've tried to look for a solution and the solutions that I've found said that it's because I'm trying to update the field with a value that is different but I don't understand why because the field is suppose to be the same.
The databases I have the problem with
This is the html part:
<asp:DropDownList ID="ItemType" runat="server">
<asp:ListItem></asp:ListItem>
</asp:DropDownList></td>
This is my code at the PageLoad:
if (!Page.IsPostBack)
{
DataTable dtItem = s.GetItemByIdForUser(Session["ItemCode"].ToString(),Session["Name"].ToString());
ItemCode.Text = dtItem.Rows[0][0].ToString();
ItemName.Text = dtItem.Rows[0][1].ToString();
ItemDes.Text = dtItem.Rows[0][2].ToString();
DataTable Types = s.GetAllItemsTypes();
for (int i = 0; i < Types.Rows.Count; i++)
ItemType.Items.Add(Types.Rows[i][0].ToString());
ItemType.SelectedItem.Text = dtItem.Rows[0][3].ToString();
ItemPrice.Text = dtItem.Rows[0][4].ToString();
Stock.Text = dtItem.Rows[0][5].ToString();
SellerName.Text = dtItem.Rows[0][6].ToString();
Image1.ImageUrl = "~/ProjectPictures/" + dtItem.Rows[0][8].ToString();
}
This is my code that happens when i click at the update:
DataTable dtItem = s.GetItemByIdForUser(Session["ItemCode"].ToString(), Session["Name"].ToString());
i.ItemCode = ItemCode.Text;
i.Name = ItemName.Text;
i.Des = ItemDes.Text;
i.Type = ItemType.SelectedItem.ToString();
i.Price = ItemPrice.Text;
i.Stock = Stock.Text;
i.UserName = SellerName.Text;
if (Pic.HasFile)
{
Pic.SaveAs(Server.MapPath("ProjectPictures/") + Pic.FileName);
i.Pic = Pic.FileName;
}
else
{
i.Pic = dtItem.Rows[0][8].ToString();
}
s.UpdateItem(i, ItemCode.Text);
Session["ItemCode"] = null;
Response.Redirect("Main.aspx");
and this is the sql sentence
string sql = "UPDATE [Items] SET [ItemName]= '#p1' , [ItemDes] = '#p2' , [ItemType] = '#p3' , [Price] = '#p4' , [Stock] = '#p5', [ItemPic] = '#p6' where [ItemCode] = '" +itemCode+ "'";
OleDbCommand cmd = new OleDbCommand(sql);
cmd.Parameters.Add(new OleDbParameter("#p1", OleDbType.VarChar));
cmd.Parameters["#p1"].Value = i.Name;
cmd.Parameters.Add(new OleDbParameter("#p2", OleDbType.VarChar));
cmd.Parameters["#p2"].Value = i.Des;
cmd.Parameters.Add(new OleDbParameter("#p3", OleDbType.VarChar));
cmd.Parameters["#p3"].Value = i.Type;
cmd.Parameters.Add(new OleDbParameter("#p4", OleDbType.VarChar));
cmd.Parameters["#p4"].Value = i.Price;
cmd.Parameters.Add(new OleDbParameter("#p5", OleDbType.VarChar));
cmd.Parameters["#p5"].Value = i.Stock;
cmd.Parameters.Add(new OleDbParameter("#p6", OleDbType.VarChar));
cmd.Parameters["#p6"].Value = i.Pic;

The problem is in your update statement. You have single quotation marks surrounding the parameter names. This means that they are interpreted as literal strings and not as the names of the parameter. So your statement is telling the database to update the ItemType with the value '#p3', (which is not a value in your ItemTypes table hence the foreign key violation) and not with the value in the parameter. In fact your parameters are being totally ignored.
Please also remember when using OleDB that the parameter names are ignored. All that matters is that you provide the parameters in the correct order.
Change your sql to this:
string sql = "UPDATE [Items] SET [ItemName]= #p1 , [ItemDes] = #p2 , [ItemType] = #p3 , [Price] = #p4 , [Stock] = #p5, [ItemPic] = #p6 where [ItemCode] = '" +itemCode+ "'";

Related

Writing SQL statement to select from multiple rows

This might be a silly question to ask. I will appreciate any kind of help.
I'm trying to write a query that count the number of rows based on the logic as below:
count no rows where username = #username and friendsname = #friendsname and username = #friendsname and #friendsname = #username where status = 0
consider the table in the diagram below:
The query should return 1 since id '18' and id '20' have reciprocal values. How will this query be written?
I have written the query as follows which doesn't work:
bool flag = false;
StringBuilder query = new StringBuilder();
query.Append("SELECT Count(id) from friends where username=#username AND friend_username=#friend_username AND username = #friend_username AND friend_username = #username");
query.Append(" AND status=0");
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("#username", username));
cmd.Parameters.Add(new SqlParameter("#friend_username", friendusername));
if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
flag = true;
}
}
return flag;
If I'm not mistaken you're trying to count rows given a specific #username and #friendusername that have reciprocal values based on your conditions.
Below query should help, though - I have not tested it in action!
SELECT COUNT(*) as reciprocal_values_no
FROM table_name tbl1
WHERE
username = #username
AND friend_username = #friendusername
AND status = 0
AND EXISTS (
SELECT 1 FROM table_name tbl2 WHERE tbl1.username = tbl2.friend_username AND tbl1.friend_username = tbl2.username )
try this
select username,friend_username,status, count(*)
from table_name
group by username,friend_username,status
having count(*) > 1

"Procedure or function 'UPDATE' expects parameter '#Id', which was not supplied" in Windows Form

We created a Windows Form to update a table in SQL Server.
First I click Enter ID to retrieve details from database, then after changing some data, when I click on Update button, I get an error:
Procedure or function 'UPDATE' expects parameter '#Id', which was not supplied.
Windows Form Design :
Click here
Error :
Click here
Code for Windows Form:
public partial class Update : Form
{
string connectionString = #"Data Source=AMAR;Initial Catalog=Hotel;Integrated Security=True";
public Update()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
{
TestObject t = null;
string spName = "Get";
//string queryText = "Select * from TestTable where Id = " +txtId.Text;
SqlConnection conn = new SqlConnection(connectionString);
//SqlCommand com = new SqlCommand(spName, conn);
SqlCommand com = new SqlCommand(spName, conn);
com.Parameters.AddWithValue("#Id", ID.Text);
com.CommandType = CommandType.StoredProcedure;
conn.Open();
using (SqlDataReader reader = com.ExecuteReader())
{
t = new TestObject();
while (reader.Read())
{
t.Id = reader["ID"].ToString();
t.Status = reader["Status"].ToString();
t.FName = reader["FirstName"].ToString();
t.LName = reader["LastName"].ToString();
t.Addr = reader["Address"].ToString();
t.City = reader["City"].ToString();
t.State = reader["State"].ToString();
t.Country = reader["Country"].ToString();
t.PhoneNo = reader["PhoneNo"].ToString();
t.Email = reader["EmailId"].ToString();
t.Pin = reader["Pincode"].ToString();
t.CheckIn = reader["CheckIn"].ToString();
t.CheckOut = reader["CheckOut"].ToString();
t.AdultNo = reader["AdultNo"].ToString();
t.ChildNo = reader["InfantNo"].ToString();
t.InfantNo = reader["InfantNo"].ToString();
t.RoomNo = reader["RoomNo"].ToString();
};
}
Statustxt.Text = t.Status;
txtfName.Text = t.FName;
txtlName.Text = t.LName;
txtAddr.Text = t.Addr;
City.Text = t.City;
State.Text = t.State;
Country.Text = t.Country;
PhoneNo.Text = t.PhoneNo;
EmailID.Text = t.Email;
Pincode.Text = t.Pin;
CheckIN.Text = t.CheckIn;
CheckOut.Text = t.CheckOut;
Adult.Text = t.AdultNo;
Child.Text = t.ChildNo;
Infant.Text = t.InfantNo;
RoomNo.Text = t.RoomNo;
}
}
private void btnUpdate_Click(object sender, EventArgs e)
{
string Stat = Statustxt.Text;
string FirstName = txtfName.Text;
string LastName = txtlName.Text;
string Address=txtAddr.Text;
string Cities=City.Text;
string States= State.Text;
string Countries =Country.Text;
string PhoneNos= PhoneNo.Text;;
string EmailId= EmailID.Text;
string PinCode=Pincode.Text;
string CIn=CheckIN.Text;
string COut=CheckOut.Text;
string AdultNo=Adult.Text;
string ChildNo=Child.Text;
string InfantNo=Infant.Text;
string RoomNos=RoomNo.Text;
TestObject obj = new TestObject();
obj.Stat=Statustxt.Text;
obj.FirstName = txtfName.Text;
obj.LastName = txtlName.Text;
obj.Address=txtAddr.Text;
obj.Cities=City.Text;
obj.States= State.Text;
obj.Countries =Country.Text;
obj.PhoneNos= PhoneNo.Text;;
obj.EmailId= EmailID.Text;
obj.PinCode=Pincode.Text;
obj.CIn=CheckIN.Text;
obj.COut=CheckOut.Text;
obj.AdultNo=Adult.Text;
obj.ChildNo=Child.Text;
obj.InfantNo=Infant.Text;
obj.RoomNos=RoomNo.Text;
string spName = "UPDATE";
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand com = new SqlCommand(spName, conn);
conn.Open();
com.Parameters.AddWithValue("#Stat", obj.Stat);
com.Parameters.AddWithValue("#FirstName", obj.FirstName);
com.Parameters.AddWithValue("#LastName", obj.LastName);
com.Parameters.AddWithValue("#Address", obj.Address);
com.Parameters.AddWithValue("#Cities", obj.Cities);
com.Parameters.AddWithValue("#States", obj.States);
com.Parameters.AddWithValue("#Countries", obj.Countries);
com.Parameters.AddWithValue("#PhoneNos", obj.PhoneNos);
com.Parameters.AddWithValue("#EmailId", obj.EmailId);
com.Parameters.AddWithValue("#PinCode", obj.PinCode);
com.Parameters.AddWithValue("#CIn", obj.CIn);
com.Parameters.AddWithValue("#COut", obj.COut);
com.Parameters.AddWithValue("#AdultNo", obj.AdultNo);
com.Parameters.AddWithValue("#ChildNo", obj.ChildNo);
com.Parameters.AddWithValue("#InfantNo", obj.InfantNo);
com.Parameters.AddWithValue("#RoomNos", obj.RoomNos);
com.CommandType = CommandType.StoredProcedure;
com.ExecuteNonQuery();
conn.Close();
MessageBox.Show("Customer Details updated in system");
}
}
SQL Server stored procedure:
ALTER PROCEDURE [dbo].[UPDATE]
#Id int,
#Stat nvarchar(100),
#FirstName nvarchar(100),
#LastName nvarchar(100),
#Address nvarchar(100),
#Cities nvarchar(100),
#States nvarchar(100),
#Countries nvarchar(100),
#PhoneNos int,
#EmailId nvarchar(100),
#PinCode int,
#CIn nvarchar(100),
#COut nvarchar(100),
#AdultNo int,
#ChildNo int,
#InfantNo int,
#RoomNos int
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
UPDATE [Hotel].[dbo].[Details] SET
[Status] = #Stat,
[FirstName] = #FirstName,
[LastName] = #LastName,
[Address] = #Address,
[City] = #Cities,
[State] =#States ,
[Country] = #Countries,
[PhoneNo] = #PhoneNos,
[EmailId] = #EmailId,
[Pincode] = #PinCode,
[CheckIn] = #CIn,
[CheckOut] = #COut,
[AdultNo] = #AdultNo,
[ChildNo] = #ChildNo,
[InfantNo] = #InfantNo,
[RoomNo] = #RoomNos
WHERE ID = #Id
END
a. as Mitch Wheat wrote in the comments, NEVER use keywords as procedures names.
b. as marc_s wrote in his comment - stop using .AddWithValue(). read the article he links to.
c. you never provide the #id parameter to the command , this is why you get the error.
d. this has nothing to do with winforms.
e. in the future, Please provide only the relevant code. if the problem is in the update button click, we don't need to see the entire form class, only the button click event handler.

Upper Function Input parameter in Oracle

I try to prevent SQL injection in SQL query. I used following code to do it but unfortunately I faced some problem. The query is not running in oracle DB:
strQuery = #"SELECT PASSWORD FROM IBK_USERS where upper(user_id) =upper(:UserPrefix) AND user_suffix=:UserSufix AND STATUS_CODE='1'";
//strQuery = #"SELECT PASSWORD FROM IBK_CO_USERS where user_id = '" + UserPrefix + "' AND user_suffix='" + UserSufix + "' AND STATUS_CODE='1'";
try
{
ocommand = new OracleCommand();
if (db.GetConnection().State == ConnectionState.Open)
{
ocommand.CommandText = strQuery;
ocommand.Connection = db.GetConnection();
ocommand.Parameters.Add(":UserSufix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserSufix"].Value = UserSufix;
ocommand.Parameters.Add(":UserPrefix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserPrefix"].Value = UserPrefix.ToUpper();
odatareader = ocommand.ExecuteReader();
odatareader.Read();
if (odatareader.HasRows)
{
Your parameters shouldn't contain the semicolon :. This is just an indicator in your query that the variable that follows is a parameter, but you don't have to supply that on the .NET side:
ocommand.Parameters["UserSufix"] = ...

SQL: Update does not affect any row

I want to update a dataset in a DB2/AS400 table.
The problem is if I there is string parameter in the parameters list the command does not find a row to update.
For example: If I run the command only with the company number the command will succeed. If I run the command with the company number and facility number the command fails.
Does anyone have any idea?
IDbConnection cn = Tools.GetCnApp();
try
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("UPDATE " + Tools.GetSchemeApp() + "/ChangeReasonAssignments");
sql.AppendLine(" SET Confirmed = #CONF, Confirmed_By = #CONFBY, Confirmed_At = #CONFAT");
sql.AppendLine(" WHERE Company = #CONO AND Facility = #FACI AND Department = #DEPT");
sql.AppendLine(" AND Production_Group = #PRGR AND Manufacturing_Order = #ORDR AND Order_Operation = #OPER");
sql.AppendLine(" AND Confirmed = 0");
IDbCommand cmd = cn.CreateCommand();
cmd.SetParameter("#CONO", this.CompanyNumber);
cmd.SetParameter("#FACI", this.FacilityNumber);
cmd.SetParameter("#DEPT", this.ProductionGroup.Department.Name);
cmd.SetParameter("#PRGR", this.ProductionGroup.Name);
cmd.SetParameter("#ORDR", this.ManufacturingNumber);
cmd.SetParameter("#OPER", this.OperationNumber);
cmd.SetParameter("#CONFBY", Base.User);
cmd.SetParameter("#CONFAT", DateTime.Now.ToString());
cmd.SetParameter("#CONF", 1);
cmd.CommandText = sql.ToString();
if (cmd.ExecuteNonQuery() > 0)
{
}
EDIT
The datatypes in database are:
Company: INTEGER
Facility: VARCHAR
Dpartment: VARCHAR
Production_Group: VARCHAR
Manufacturing_Order:INTEGER
Order_Operation: INTEGER
The datatypes in .NET are:
CompanyNumber: int
FacilityNumber: String
Departmentname: String
ProductionGroup: String
Manufacturingorder: int
OrderOperation: int
sql.ToString() results:
UPDATE TSAEDBDEV/ChangeReasonAssignments SET Confirmed = #CONF, Confirmed_By = #CONFBY, Confirmed_At = #CONFAT WHERE Company = #CONO AND Facility = #FACI AND Confirmed = 0
Try to set the string values into ': cmd.SetParameter("#DEPT", "'" + this.ProductionGroup.Department.Name + "'");

sql statement supposed to have 2 distinct rows, but only 1 is returned

I have an sql statement that is supposed to return 2 rows. the first with psychological_id = 1, and the second, psychological_id = 2. here is the sql statement
select * from psychological where patient_id = 12 and symptom = 'delire';
But with this code, with which I populate an array list with what is supposed to be 2 different rows, two rows exist, but with the same values: the second row.
OneSymptomClass oneSymp = new OneSymptomClass();
ArrayList oneSympAll = new ArrayList();
string connStrArrayList = "Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\PatientMonitoringDatabase.mdf; " +
"Initial Catalog=PatientMonitoringDatabase; " +
"Integrated Security=True";
string queryStrArrayList = "select * from psychological where patient_id = " + patientID.patient_id + " and symptom = '" + SymptomComboBoxes[tag].SelectedItem + "';";
using (var conn = new SqlConnection(connStrArrayList))
using (var cmd = new SqlCommand(queryStrArrayList, conn))
{
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
oneSymp.psychological_id = Convert.ToInt32(rdr["psychological_id"]);
oneSymp.patient_history_date_psy = (DateTime)rdr["patient_history_date_psy"];
oneSymp.strength = Convert.ToInt32(rdr["strength"]);
oneSymp.psy_start_date = (DateTime)rdr["psy_start_date"];
oneSymp.psy_end_date = (DateTime)rdr["psy_end_date"];
oneSympAll.Add(oneSymp);
}
}
conn.Close();
}
OneSymptomClass testSymp = oneSympAll[0] as OneSymptomClass;
MessageBox.Show(testSymp.psychological_id.ToString());
the message box outputs "2", while it's supposed to output "1". anyone got an idea what's going on?
You're adding the same instance to the ArrayList twice. Try this:
List<OneSymptomClass> oneSympAll = new List<OneSymptomClass>();
string connStrArrayList =
"Data Source=.\\SQLEXPRESS;" +
"AttachDbFilename=|DataDirectory|\\PatientMonitoringDatabase.mdf; " +
"Initial Catalog=PatientMonitoringDatabase; " +
"Integrated Security=True";
Patient patientID;
string queryStrArrayList =
"select * from psychological where patient_id = " +
patientID.patient_id + " and symptom = '" +
SymptomComboBoxes[tag].SelectedItem + "';";
using (var conn = new SqlConnection(connStrArrayList))
{
using (var cmd = new SqlCommand(queryStrArrayList, conn))
{
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
OneSymptomClass oneSymp = new OneSymptomClass();
oneSymp.psychological_id =
Convert.ToInt32(rdr["psychological_id"]);
oneSymp.patient_history_date_psy =
(DateTime) rdr["patient_history_date_psy"];
oneSymp.strength = Convert.ToInt32(rdr["strength"]);
oneSymp.psy_start_date =
(DateTime) rdr["psy_start_date"];
oneSymp.psy_end_date =
(DateTime) rdr["psy_end_date"];
oneSympAll.Add(oneSymp);
}
}
conn.Close();
}
}
MessageBox.Show(oneSympAll[0].psychological_id.ToString());
MessageBox.Show(oneSympAll[1].psychological_id.ToString());
Note that I replaced the ArrayList with a List<OneSymptomClass>. There is no reason to use ArrayList unless you're using .NET 1.1.
thx for the tip John Saunders. I added a line that makes it work. was that what you were gonna suggest me?
while (rdr.Read())
{
oneSymp = new OneSymptomClass();
oneSymp.psychological_id = Convert.ToInt32(rdr["psychological_id"]);
oneSymp.patient_history_date_psy = (DateTime)rdr["patient_history_date_psy"];
oneSymp.strength = Convert.ToInt32(rdr["strength"]);
oneSymp.psy_start_date = (DateTime)rdr["psy_start_date"];
oneSymp.psy_end_date = (DateTime)rdr["psy_end_date"];
oneSympAll.Add(oneSymp);
}