How to insert list of data into mysql table - c#

I have a table which contains a single column "CODE_CAR".
I want to populate this table with list of string as below :
_Connection.Open();
var lst_code_cars = new List<string> { "YH_21", "NM_00", "BAR_N178" };
string cmdText = "INSERT INTO Y157.CARS_IDENDITY(CODE_CAR) VALUES ("+lst_code_cars+")";
MySqlCommand cmd = new MySqlCommand(cmdText, _Connection);
foreach (string cars_code in lst_code_cars )
{
cmd.Parameters.AddWithValue("#"+cars_code , cars_code );
cmd.ExecuteNonQuery();
}
_Connection.Close();
When i try this code, i get error : MySqlException : Parameter '#NM_00' must be defined.

The error tells you exactly what is wrong. You did not define a parameter, you concatenated the value directly into the query string. So don't do that.
_Connection.Open();
var lst_code_cars = new List<string> { "YH_21", "NM_00", "BAR_N178" };
string cmdText = "INSERT INTO Y157.CARS_IDENDITY(CODE_CAR) VALUES (#CarCode)";
MySqlCommand cmd = new MySqlCommand(cmdText, _Connection);
foreach (string cars_code in lst_code_cars )
{
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#CarCode" , cars_code );
cmd.ExecuteNonQuery();
}
_Connection.Close();
You'll also need to clear the parameters if you mean to re-add them each loop. Either that or add the parameter once and then edit the value in the loop instead of adding a new parameter each time.
Ideally, though, you could write this as a batch insert.

Related

Parameter '#stIdCity' was supplied multiple times asp.net c#

I am trying to send values to a stored procedure via a listbox containing country names I get them from the database. If I choose one option code works 100% 100%. But if I put 2 or 3 options, I get the following error:
Parameter '#stIdCity' was supplied multiple times.
Line 322: da.Fill(ds);
Full code:
protected void lstBoxTestCity_SelectedIndexChanged(object sender, EventArgs e)
{
string str = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(str))
{
using (SqlCommand cmd = new SqlCommand("Tprocedure", con))
{
cmd.CommandType = CommandType.StoredProcedure;
foreach (ListItem item in lstBoxTestCity.Items)
{
if (item.Selected)
{
cmd.Parameters.AddWithValue("#stIdCity", item.Value);
}
}
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
gvProducts.DataSource = ds;
gvProducts.DataBind();
}
}
}
Stored procedure:
CREATE PROCEDURE Tprocedure
(#stIdCity NVARCHAR(20) = NULL, )
AS
BEGIN
SELECT *
FROM employees
INNER JOIN TCity ON employees.IdstICity = TCity.IdstICity
WHERE (employees.IdstICity IN (SELECT ITEM
FROM dbo.SplitString(#stIdCity, ','))
OR ISNULL(#stIdCity, '') = '')
END
Image of list:
Please help to solve the problem.
Sorry if the question was repeated, but I could not find a solution to it.
You have this:
foreach (ListItem item in lstBoxTestCity.Items)
{
if (item.Selected)
{
cmd.Parameters.AddWithValue("#stIdCity", item.Value);
}
}
so for each selected city, you add a new parameter. That is why you get that error message.
Apparently you want one parameter, with a comma-separated value. So build that:
var value = string.Join(",",lstBoxTestCity.Items.Where(it => it.IsSelected).Select(it => it.Value));
cmd.Parameters.Add("#stIdCity", SqlDbType.NVarChar, 20).Value = value;
First I use LINQ to filter for selected items, then I get their value. string.Join combines the resulting values with commas.
But do note that your stored procedure accepts just a nvarchar(20), so you may run out of space when multiple cities have been selected.
You ONLY have the ONE parmater, and it is a comma delimited string of values.
So, you have to "build up" a comma delimited string. Say like this:
string myparms = "";
foreach (ListItem item in lstBoxTestCity.Items)
{
if (item.Selected)
{
if (myparms != "")
myparms += ",";
myparms += item.Value;
}
}
cmd.Parameters.Add("#stIdCity",SqlDbType.NVarChar).Value = myparms;
So, you only passing one value - but you have to build up the "string" of values to pass.

Access parametrized IN() query

I am trying to run this query:
SELECT * FROM Tabela1 WHERE Pole1 IN (#parameter)
When the window with "choose value" appears, I put: "10, 50" and I receive 0 rows (should be 2).
When I put only "10", or only "50" it works and returns 1 row for each query.
I am using Access 2013 - what am I doing wrong?
using (DbConnection connection = new T())
{
connection.ConnectionString = query.DatabaseConnection.ConnectionString;
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = query.QuerySql.Sql;
command.CommandType = CommandType.Text;
command.CommandTimeout = query.QuerySql.CommandTimeout;
if (query.QuerySql.Parameters != null)
{
foreach (var parameter in query.QuerySql.Parameters)
{
var commandParameter = command.CreateParameter();
commandParameter.ParameterName = $"#{parameter.Name}";
commandParameter.Value = parameter.Value;
command.Parameters.Add(commandParameter);
}
}
I create the query like that:
QuerySql sql = new QuerySql("SELECT * FROM Tabela1 WHERE Pole1 IN(#parameter)", new List<ISqlParameter>()
{
new SqlMultiNumberParameter("parameter", new List<string>() { "10", "50" }, "Test parameter")
});
the parameter.Value returns string like that: "10, 50"
Best regards
Michael
You cannot use a single parameter to express a list of values to be passed to an IN clause. There are some ORM (like Dapper for example) that allows you to pass a list of values and build for you the correct IN clause.
If you want to do the same thing you need something like this method
public OleDbCommand GetPoles(List<int> polesID)
{
// Base text of the query
string cmdText = #"SELECT * FROM TABLE1 WHERE Pole1 IN(";
// where we store the 'name' of the parameters. (OleDb doesn't care)
List<string> inClause = new List<string>();
// where we store the parameters and their values
List<OleDbParameter> parameters = new List<OleDbParameter>();
foreach(int id in polesID)
{
// Add a placeholder for the parameter
inClause.Add("?");
// Build the parameter and store it away
OleDbParameter p = new OleDbParameter("p" + id.ToString(), OleDbType.Integer);
p.Value = id;
parameters.Add(p);
}
OleDbCommand cmd = new OleDbCommand();
// Build the command text: IN(?,?,?). A ? placeholder for each parameter
cmd.CommandText = cmdText + string.Join(",", inClause.ToArray()) + ")";
// pass all the parameters to the command and return it
cmd.Parameters.AddRange(parameters.ToArray());
return cmd;
}
Now you just need to set the connection and you can execute the command

Extract Contents of DataSet into an Object

I have this DataSet which calls my Stored Procedure and returns a list of integers. How can I extract the list of integers which I could store in a variable be it a collection which grows in size such as a List<T> or a primitive data type like an array of integers.
Below is my code:
private DataSet getSubGroupsBelongingToUser()
{
DataTable variable;
DataSet DS;
myConnectionString = ConfigurationManager.ConnectionStrings["FSK_ServiceMonitor_Users_Management.Properties.Settings.FSK_ServiceMonitorConnectionString"].ConnectionString;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
SqlParameter param = new SqlParameter("#UserId", getUserID(cbxSelectUser.Text));
DS = GetData("Test", param);
variable = DS.Tables[0];
}
return DS;
}
When I hover over the DS magnifier (refer to image):
I want to retrieve and store that list of integers somewhere. How can I go about doing this? All the examples I came across online make use of linq and that is not applicable here since I am getting the results from my stored procedure which requires one input parameter. Here is the definition of the stored procedure below:
create proc [dbo].[Test]
#UserId smallint
as
begin
select DepartmentSubGroupId from DepartmentSubGroupUser
where UserId= #UserId
end
GO
So essentially when you pass in a UserId, you should get those values. I am using SQL Server as my DBMS.
The simplest and most efficient approach would be to not use a DataSet/DataTable at all:
private List<int> GetSubGroupsBelongingToUser()
{
List<int> list = new List<int>();
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["FSK_ServiceMonitor_Users_Management.Properties.Settings.FSK_ServiceMonitorConnectionString"].ConnectionString))
using (var cmd = new SqlCommand("Test", con))
{
cmd.CommandType = CommandType.StoredProcedure;
var param = new SqlParameter("#UserId", SqlDbType.Int).Value = int.Parse(cbxSelectUser.Text);
cmd.Parameters.Add(param);
con.Open();
using (var rd = cmd.ExecuteReader())
{
while (rd.Read()) list.Add(rd.GetInt32(0));
}
} // no need to close the connection with the using
return list;
}
If you insist on the DataTable, at least it's more conscise:
return DS.Tables[0].AsEnumerable().Select(r => r.Field<int>(0)).ToList();
As #David pointed out the simplest option would be to use a SqlDataReader and loop through all the records.
However, if your heart is set on DataTables then all you need to do is to iterate all rows from the result table, grab the value from column DepartmentSubGroupId and add it to a list. You can do that with Linq also like this:
return DS.Tables[0].Rows
.Cast<DataRow>() // Rows is an ICollection and you need to cast each item
.Select(r => (int)r["DepartmentSubGroupId"]) // For each row get the value from column DepartmentSubGroupId
.ToList();
Before I saw #Tim's solution, I had already prepared this (which works just as well as most of the above solutions):
public List<int> getSubGroupsBelongingToUser()
{
List<int> DepartmentSubGroupIds = new List<int>();
myConnectionString = ConfigurationManager.ConnectionStrings["FSK_ServiceMonitor_Users_Management.Properties.Settings.FSK_ServiceMonitorConnectionString"].ConnectionString;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
SqlParameter parameter = new SqlParameter("#UserId", getUserID(cbxSelectUser.Text));
mySQLCommand = new SqlCommand("Test", mySQLConnection);
mySQLCommand.CommandType = CommandType.StoredProcedure;
mySQLCommand.Parameters.Add(parameter);
mySQLConnection.ConnectionString = myConnectionString;
mySQLConnection.Open();
SqlDataReader sqlDataReader = mySQLCommand.ExecuteReader();
while (sqlDataReader.Read())
{
DepartmentSubGroupIds.Add(Convert.ToInt32(sqlDataReader["DepartmentSubGroupId"]));
}
}
return DepartmentSubGroupIds;
}
Thanks everybody, much appreciated.

How to insert each line of a Textbox lines to a database (line by line) using a foreach loop?

I want to insert each line of a Textbox lines to a row of database (line by line) when its TextMode property is Multiline using a foreach loop? I used this code but it inserts all the lines in one row of my "ChTB" table. What is wrong with it?
string ID = null;
DateTime RegDtTime = DateTime.UtcNow;
SqlConnection con1 = new SqlConnection(connectionString);
string sql1 = "SELECT * FROM ChTB";
SqlCommand command1 = new SqlCommand(sql1, con1);
con1.Open();
foreach (object line_loopVariable in this.Textbox1.Text.Split({ Environment.NewLine }, StringSplitOptions.None)) {
line = line_loopVariable;
ID = line;
string commandText = "insert into ChTB(ID,Visible,RegDtTime,LastDateTime) values(#ID,#Visible,#RegDtTime,#LastDateTime)";
SqlCommand cmdObj = new SqlCommand(commandText, con1);
cmdObj.Parameters.AddWithValue("#ID", ID);
cmdObj.Parameters.AddWithValue("#Visible", "NO");
cmdObj.Parameters.AddWithValue("#RegDtTime", RegDtTime);
cmdObj.Parameters.AddWithValue("#LastDateTime", RegDtTime);
cmdObj.ExecuteNonQuery();
}
con1.Close();
Why are you using three different variables for the same value? Just do this:
foreach (var line in myTextBox.Lines)
{
// Use line here.
}
As for the insert, don't create a new command object every time and add new parameters. Create one object, add the parameters and then set their Value properties each time, e.g.
var command = new SqlCommand("INSERT INTO MyTable (SomeColumn) VALUES (#SomeColumn)", connection)
var parameter = command.Parameters.Add("#SomeColumn", SqlDbType.VarChar, 50)
foreach (var line in myTextBox.Lines)
{
parameter.Value = line
// Execute command here.
}

Parameterized queries on iteration

I am inserting a web form into the database and so using parameterized queries. I have a CheckBoxList. How can I iterate over CheckBoxList, create an insert statement for every checked thing (many-to-many), and keep this parameterized and executed in one swoop?
I have this right now:
string query = "INSERT INTO resources (url, submitted_by, author_name) VALUES (#url, #submitted_by, #author_name);";
foreach (ListItem li in CheckBoxList1.Items)
{
if (li.Selected = true)
{
query += "; INSERT INTO ";
}
}
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#url", TextBox1.Text);
cmd.Parameters.AddWithValue("#submitted_by", TextBox2.Text);
cmd.Parameters.AddWithValue("#author_name", TextBox3.Text);
try
{
conn.Open();
cmd.ExecuteNonQuery();
Label1.Text = "Added to database.";
}
As you can see it's unfinished. Any suggestions?
You could use LINQ to generate unique named parameters for each item in your collection, then add the associated values in later:
var builder = new StringBuilder();
var listParams = CheckBoxList1.Items
.Where(li => li.Selected)
.Select(li, idx => new
{
PhoneString = String.Format("#phone_id{0}", idx),
PhoneValue = GetPhoneId(li),
ResourceString = String.Format("#resource_id{0}", idx),
ResourceValue = GetResourceId(li)
};
foreach (var param in listParams)
{
builder.AppendFormat("INSERT INTO phones_resources (phone_id, resource_id)
VALUES ({0}, {1});",
param.PhoneString, param.ResourceString);
}
SqlCommand cmd = new SqlCommand(builder.ToString(), conn);
foreach (var param in listParams)
{
cmd.Parameters.AddWithValue(param.PhoneString, param.PhoneValue);
cmd.Parameters.AddWithValue(param.ResourceString, param.ResourceValue);
}
I'm assuming you have some way of getting associated phone_id, resource_id from any given ListItem - you can just plug that in where I've put the placeholder Get___ functions.
Note: Switched to a StringBuilder - it's much better than building up a string with repeated +=.

Categories

Resources