I keep getting this error when I try to find by ID:
system.data.oledb.oledbexception the speciefied field 'ID' could refer
to more than one table listed in the FROM clause of your SQL Statement
Here's my code:
public static Invoice GetInvoice(string id)
{
OleDbConnection conn = GetConnection();
Invoice invoice = null;
if (conn == null)
{
return null;
}
string sqlString = "SELECT * FROM Person INNER JOIN Employee ON " +
"Person.ID=Employee.ID WHERE ID = #ID";
OleDbCommand comm = new OleDbCommand(sqlString, conn);
comm.Parameters.AddWithValue("#ID", id);
OleDbDataReader dr = null;
try
{
conn.Open();
dr = comm.ExecuteReader(CommandBehavior.SingleRow);
if (dr.Read())
{
invoice = new Invoice();
invoice.PersonID = (string)dr["ID"];
invoice.FirstName = (string)dr["FirstName"];
invoice.LastName = (string)dr["LastName"];
invoice.Age = (int)dr["Age"];
}
}
catch (Exception ex)
{
invoice = null;
MessageBox.Show(ex.ToString());
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
return invoice;
}
You need to change your query, at the moment you're selecting a wildcard '*', which means it will pull both the Persons ID and the Employee ID, but wont have a unique reference. Change your wildcard to pull the exact tables ID like below:
SELECT Person.ID, FirstName, LastName FROM...
You will also need to change your WHERE statement to something like:
WHERE Person.ID = #ID
as the where statement doesnt know which tables ID to filter on (i know they're the same values, but SQL doesnt care about that)
Related
Currently, I am using MVC on creating a project. Now I want to insert an Identity ID value into an INSERT statement.
In my controller:
string payment = #"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount)
VALUES('{0}','{1}',{2})";
int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
if (pay == 1)
{
string pid = "SELECT TOP 1 Payment_id FROM Payment ORDER BY Payment_id DESC";
int paymentid = DBUtl.ExecSQL(pid);
if (cart.Count() != 0)
{
string order = #"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id)
VALUES('{0}','{1}',{2},{3})";
Now, I want to the payment_id that already been inserted into the payment table which is the first statement and retrieve the payment_id and use it into the INSERT statement for the Order table
How can I achieve that?
Please Help
Thank you
Actually, DBUtil code consists of:
public static int ExecSQL(string sql, params object[] list)
{
List<String> escParams = new List<String>();
foreach (object o in list)
{
if (o == null)
escParams.Add("");
else
escParams.Add(EscQuote(o.ToString()));
}
DB_SQL = String.Format(sql, escParams.ToArray());
int rowsAffected = 0;
using (SqlConnection dbConn = new SqlConnection(DB_CONNECTION))
using (SqlCommand dbCmd = dbConn.CreateCommand())
{
try
{
dbConn.Open();
dbCmd.CommandText = DB_SQL;
rowsAffected = dbCmd.ExecuteNonQuery();
}
catch (System.Exception ex)
{
DB_Message = ex.Message;
rowsAffected = -1;
}
}
return rowsAffected;
}
And as you know ExecuteNonQuery denotes the numbers affecting the row
So, You can do as shown below:
FOR SQL SERVER 2005 and above
using (SqlConnection con=new SqlConnection(#"Your connectionString"))
{
using(SqlCommand cmd=new SqlCommand("INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) output INSERTED.Payment_id VALUES(#Payment_Method,#Currency_Type,#Total_Amount)",con))
{
cmd.Parameters.AddWithValue("#Payment_Method", "Cash");
cmd.Parameters.AddWithValue("#Currency_Type", currency);
cmd.Parameters.AddWithValue("#Total_Amount", total);
con.Open();
int payment_id =Convert.ToInt32(cmd.ExecuteScalar());
if (con.State == System.Data.ConnectionState.Open)
con.Close();
return payment_id ;
}
}
also, you can change your query to:
"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) VALUES(#Payment_Method,#Currency_Type,#Total_Amount)"; SELECT SCOPE_IDENTITY()"
For now, I tried something like this:
public IActionResult SaveDetail(List<Cart_Has_Services> cart,double total,string currency)
{
string payment = #"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount)
VALUES('{0}','{1}',{2});";
int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
if (pay == 1)
{
object pid = DBUtl.GetList("SELECT Payment_id FROM Payment");
int paymentid = Convert.ToInt32(pid);
if (cart.Count() != 0)
{
string order = #"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id)
VALUES('{0}','{1}',{2},{3})";
foreach (var item in cart)
{
int ord = DBUtl.ExecSQL(order, item.Cart_Service, item.Additional_Notes, item.Quantity,paymentid);
As for now, the codes will run by inserting the values into the payment table. After that, I want to get the payment_id for my next insert which is the order table.
The method that I tried to get the payment_id does not work.
I just keep on getting Syntax error when I used parameterized sql query.
public List<string> Cat(string product,string table)
{
List<string> Products = new List<string>();
Global global = new Global();
string sql = "SELECT #prod FROM #tbl";
MySqlConnection connection = new MySqlConnection(global.ConnectionString);
MySqlCommand command = new MySqlCommand(sql, connection);
command.Parameters.AddWithValue("#prod", product);
command.Parameters.AddWithValue("#tbl", table);
connection.Open();
MySqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
Products.Add(reader.GetString("#prod"));
}
connection.Close();
return Products;
}
public List<string> CallProducts(string category)
{
string table;
string product;
List<string> stacks = new List<string>();
if (category == "Accessories")
{
product = "Accessories_Name";
table = "tbl_accessories";
stacks.AddRange(Cat(product, table).ToArray());
}
else if (category == "Batteries")
{
table = "tbl_batteries";
}
else if (category == "Cotton")
{
table = "tbl_cotton";
}
else if (category == "Juices")
{
table = "tbl_juices";
}
else if (category == "Kits")
{
table = "tbl_kits";
}
else if (category == "Mods")
{
table = "tbl_mods";
}
else
{
table = "tbl_vapeset";
}
return stacks;
}
I just keep on getting SQL Syntax Error. It works if the table and the name is manually inputted rather than using parameters.
Hoping you can help.
Need for a project.
Thanks!
Correct use would be:
string sql = $"SELECT {product} FROM {table}";
Because table and column are not parameters.
Moreover, I would recommend using Command.Parameters.Add(...).Value(...),
over Parameters.AddWithValue, since in first approach you can explicitly decide what datatype you want to pass and prevent SQL from guessing it.
Whenever I run this query and assign values to the properties on an object it always gives me an erorr with the ADDRESS_ZIP column. Whenever I comment that particular assignment out, the values goes to the phoneHome property.
Those two columns are "nchar" types so I think that has something to do with it. Can't nail down the problem though.
public static Patient GetPatientInfo(string username)
{
SqlConnection connection = MedicalDB.EstConnection();
string selectStatement
= "SELECT PATIENT_ID, LAST_NAME, FIRST_NAME, USERNAME, DATE_Of_BIRTH, ADDRESS_STREET, ADDRESS_CITY, ADDRESS_STATE, ADDRESS_ZIP" +
" PHONE_HOME, PHONE_MOBILE FROM PATIENT_TBL WHERE username = #username";
SqlCommand selectCommand =
new SqlCommand(selectStatement, connection);
selectCommand.Parameters.AddWithValue("#username", username);
try
{
connection.Open();
SqlDataReader patientReader =
selectCommand.ExecuteReader(CommandBehavior.SingleRow);
if (patientReader.Read())
{
Patient patient = new Patient();
patient.patientID = patientReader["PATIENT_ID"].ToString();
patient.lastName = patientReader["LAST_NAME"].ToString();
patient.firstName = patientReader["FIRST_NAME"].ToString();
patient.userName = patientReader["USERNAME"].ToString();
patient.DateOfBirth = patientReader["DATE_OF_BIRTH"].ToString();
patient.addressStreet = patientReader["ADDRESS_STREET"].ToString();
patient.addressCity = patientReader["ADDRESS_CITY"].ToString();
patient.addressState = patientReader["ADDRESS_STATE"].ToString();
patient.addressZip = patientReader["ADDRESS_ZIP"].ToString();
patient.phoneHome = patientReader["PHONE_HOME"].ToString();
patient.phoneMobile = patientReader["PHONE_MOBILE"].ToString();
return patient;
}
else
{
return null;
}
}
catch (SqlException ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
You are missing a comma between ADDRESS_ZIP and PHONE_HOME (hard to see because you split it in two lines).
Hello for a project im using C# WPF applications in combination with SQL.
However when trying to run some delete statements within the application I get the following error: "collection was modified enumeration operation may not execute". I've read on the internet and tried numerous solutions but none solved my problem.
My code
The SQL query that creates the list and fills the list with all orders
public List<ProductOrder> ProductOrders(int id)
{
con = new SqlConnection(Database.StringGlenn);
ProductOrder = new List<ProductOrder>();
string query = "select po.OrderID, p.Naam, po.Aantal from ProductOrder as po inner join Product as p on po.ProductID = p.ProductID where po.OrderID ='" + id + "'";
con.Open();
cmd = new SqlCommand(query, con);
using (reader = cmd.ExecuteReader())
{
while (reader.Read())
{
ProductOrder productorder = new ProductOrder();
productorder.OrderId = Convert.ToInt32(reader["OrderID"]);
productorder.Product = reader["Naam"].ToString();
productorder.Aantal = Convert.ToInt32(reader["Aantal"]);
ProductOrder.Add(productorder);
}
}
con.Close();
return ProductOrder;
}
The delete query:
public void VerwijderOrder(int id)
{
con.Open();
foreach (ProductOrder po in ProductOrder)
{
if (po.OrderId == id)
{
string query = "delete from [Order] where OrderID = " + id;
cmd = new SqlCommand(query, con);
ProductOrder.Remove(po);
}
}
con.Close();
The code on the delete button
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
try
{
int orderId = Convert.ToInt32((DataOrders.SelectedItems[0] as Orders).OrderId);
inter.VerwijderProductOrder(orderId);
LaadOrders();
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
I've tried showing the query in a messagebox and it shows the right query so it should be working. However I keep getting this error.
You should not modify the collection inside the block when you are enumerating over it.
foreach (ProductOrder po in ProductOrder)
{
ProductOrder.Remove(po); <-- this is causing your exception
}
The fix would be to remove it outside of the block. Here you can use RemoveAll which takes a predicate.
public void VerwijderOrder(int id)
{
// code not shown has not been altered
foreach (ProductOrder po in ProductOrder)
{
if (po.OrderId == id)
{
// ProductOrder.Remove(po);
}
}
ProductOrder.RemoveAll(x => x.OrderId == id);
}
The issue, as explained in other answers is that you are removing items from the list you are iterating, but really you don't need a loop at all.
ProductOrder.RemoveAll(p=> p.OrderID == id);
Also
ALWAYS ALWAYS ALWAYS use parameterised queries.
Enclose unmanaged resources in using blocks to ensure they are properly disposed of.
You never actually execute your command
There is no benefit to re-using SqlConnection, or Command objects, I would suggest creating a new one each time
So your final code might end up as:
public void VerwijderOrder(int id)
{
con.Open();
string query = "delete from [Order] where OrderID = #id";
using (var con = new SqlConnection(connectionString))
using(var cmd = new SqlCommand(query, con))
{
con.Open();
cmd.Parameters.Add("#id", SqlDbType.Int).Value = id;
cmd.ExecuteNonQuery();
);
ProductOrder.RemoveAll(p=> p.OrderID == id);
}
Problem is, that you remove an item from the list you iterate. Just remove the items later. Possibly like this:
public void VerwijderOrder(int id)
{
List<ProductOrder> deletes = new List<ProductOrder>();
con.Open();
foreach (ProductOrder po in ProductOrder)
{
if (po.OrderId == id)
{
string query = "delete from [Order] where OrderID = " + id;
cmd = new SqlCommand(query, con);
deletes.Add(po);
}
}
con.Close();
deletes.forEach(d => ProductOrder.Remove(d));
}
You cant delete inside a foreach loop which enumerates the collection you want to delete from. This :
foreach (ProductOrder po in ProductOrders)
{
if (po.OrderId == id)
{
string query = "delete from [Order] where OrderID = " + id;
cmd = new SqlCommand(query, con);
ProductOrders.Remove(po);
}
}
Should be changed to this:
List<ProductOrder> ForRemovall=new List<ProductOrder>()
foreach (ProductOrder po in ProductOrders)
{
if (po.OrderId == id)
{
string query = "delete from [Order] where OrderID = " + id;
cmd = new SqlCommand(query, con);
ForRemovall.Add(po);
}
}
foreach (ProductOrder po in ForRemoval)
{
ProductOrders.Remove(po);
}
I fixed it, I forgot the ExecutenonQuery code;
Final code:
public void VerwijderProductOrder(int id)
{
con.Open();
string query = "delete from ProductOrder where OrderID = " + id;
cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery();
ProductOrder.RemoveAll(p => p.OrderId == id);
con.Close();
}
I am working on my windows form application using c#. I have a checkListBox that is binded to db. I am wondering is there a way to delete any duplicate record from the database?
Here is my code
private void fill_checkListBox()
{
try
{
string query = "select * from table_1 ";
SqlCommand myTeacherCommand = new SqlCommand(query, myConn);
//reading the value from the query
dr = myCommand.ExecuteReader();
//Reading all the value one by one
teacherCB.Items.Clear();
while (dr.Read())
{
string name = dr.IsDBNull(2) ? string.Empty : dr.GetString(2);
teacherCB.Items.Add(name);
if (!checkBox.Items.Contains(name))
{
teacherCB.Items.Add(name);
}
}
dr.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The first answer - use DISTINCT in query:
select distinct * from table_1
Also, I advice you to specify column names in query:
select distinct ID, Name from table_1
But I don't know anything about your data in table.