I'm creating an Inventory System which can add multiple items in a single click. how could I do this? I can already save data but for just a single textbox.
//Add new Data if Item Code is not exit;
{
OleDbCommand cmdInsert = new OleDbCommand(#"insert into TblInventory (ItemCode,ProductName,Quantity,DateAndTime) values ('" + txtItem.Text + "','" + txtProduct.Text + "','" + txtQuantity.Text + "','" + time + "')");
cmdInsert.Connection = con;
cmdInsert.ExecuteNonQuery();
MessageBox.Show("You added New " + txtQuantity.Text + " " + txtProduct.Text + " in the list", "New Item");
}
con.Close();
assuming that I have another textBoxes which are txtItem2, txtProduct2 and txtQuantity2. where can I locate those on my insert into statement?
First, use parameters instead of string concatenation, like below:
OleDbCommand cmdInsert = new OleDbCommand(
#"insert into TblInventory (ItemCode,ProductName,Quantity,DateAndTime) values (#ItemCode,#ProductName,#Quantity,#DateAndTime)");
cmdInsert.Parameters.AddWithValue("ItemCode", txtItem.Text);
cmdInsert.Parameters.AddWithValue("ProductName", txtProduct.Text);
cmdInsert.Parameters.AddWithValue("Quantity", txtQuantity.Text);
cmdInsert.Parameters.AddWithValue("DateAndTime", time);
Second, if you need many inserts, use loop. Or, wrap your insert code in function with four parameters ItemCode,ProductName,Quantity,DateAndTime. Use them instead of direct references to txtSomething.Text values, i.e. (pseudocode):
InsertRecord(txtItem.Text, txtProduct.Text, ...);
InsertRecord(txtItem2.Text, txtProduduct2.Text, ...);
For loop you can write like below:
var rows = new[]
{
new {Item = "item1" /*value from txtItem1*/, Product = "product1", Quantity = "Quantity1" /*should be int?*/},
new {Item = "item2" /*value from txtItem2*/, Product = "product2", Quantity = "Quantity2"}
};
foreach (var row in rows)
{
OleDbCommand cmdInsert = new OleDbCommand(
#"insert into TblInventory (ItemCode,ProductName,Quantity,DateAndTime) values (#ItemCode,#ProductName,#Quantity,#DateAndTime)");
cmdInsert.Parameters.AddWithValue("ItemCode", row.Item);
cmdInsert.Parameters.AddWithValue("ProductName", row.Product);
cmdInsert.Parameters.AddWithValue("Quantity", row.Quantity);
cmdInsert.Parameters.AddWithValue("DateAndTime", DateTime.Now);
cmdInsert.Connection = conn;
cmdInsert.ExecuteNonQuery();
}
You could create a stored procedure accepting xml as input parameter, and then in the stored procedure ypu will parse the xml and insert the data to the table,
Related
Im trying to perform a parameterized query in SQLite from C#, and the method im using is along the lines of creating a static command with
SQLiteCommand cmd = new SQLiteCommand(
"SELECT [ID]" +
",[email]" +
",[serializedata]" +
",[restrictions]" +
" FROM " + UserTable +
" WHERE #search = #searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("#searchparam"));
cmd.Parameters.Add(new SQLiteParameter("#search"));
and calling it like this:
Command.Parameters["#searchparam"].Value = searchdata;
Command.Parameters["#search"].Value = search;
SQLiteDataAdapter slda = new SQLiteDataAdapter(UserSelectUsernameCommand);
DataSet ds = new DataSet();
slda.Fill(ds);
User[] array = new User[ds.Tables[0].Rows.Count];
int index = 0;
foreach (DataRow row in ds.Tables[0].Rows)
{
array[index] = new User(this, row);
index++;
}
return array;
but im getting an error along the line of " '#search' is not a correct column name " or something like that. if i use a constant column name, and only use the data for parameters it works, but i dont want to create 10 different commands for when i need to search by different column names.
What is the issue here?
Generally things like column names (or table names) can not be parameterised - and the fact that there are different indices means that it will have to be a different plan internally. So you will have to use concatenation - but be careful to white-list the known column names to prevent sql injection:
SQLiteCommand cmd = new SQLiteCommand(#"
SELECT [ID],[email],[serializedata],[restrictions]
FROM " + whiteListedUserTable + #"
WHERE [" + whiteListedColumnName + #"] = #searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("#searchparam"));
...
Command.Parameters["#searchparam"].Value = searchdata;
You cannot use a query parameter in that fashion -- to indicate a column name. You can only use it to supply values.
Consider something like this instead:
SQLiteCommand cmd = new SQLiteCommand(
"SELECT [ID]" +
",[email]" +
",[serializedata]" +
",[restrictions]" +
" FROM " + UserTable +
" WHERE [" + search + "] = #searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("#searchparam"));
If you control all of the input to this function and none if it can be supplied by someone other than you, this should be safe. But if search comes from an untrusted third party, be sure to make the appropriate security checks on the value.
I'm trying to grab elements from a certain column/Listbox which has the type "numeric" and store them in a List in C#.
datTable = new DataTable();
sqlCmd = new SqlCommand(#
"SELECT DISTINCT [" + form1.getColumnName() + "]
FROM [" + form1.getTableName() + "]", connection);
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText, connection);
sqlDatAdapter.Fill(datTable);
form1.columnStorList.DisplayMember = form1.getColumnName();
form1.columnStorList.ValueMember = "Column1";
form1.costStorList.DataSource = datTable;
List<Decimal> columnElements = new List<Decimal>();
foreach (var selectedItem in form1.columnStorList.SelectedItems)
{
DataRow row = (selectedItem as DataRowView).Row;
columnElements.Add(row.Field<decimal>(form1.getColumnName()));
}
Somehow he don't want to convert it. Double doesn't work at all. For example the value '0,000000' gets displayed as '0'. I tried to convert the elements to Double but then I get '0.0'. Decimal should be the closest to Numeric or am I wrong? How to display it correctly?
I want to use a SELECT Statement (SELECT...FROM...WHERE...=0,000000) to search the value in the database when I highlight it in my Listbox. Since he cuts the values off that specific value won't get found in my database.
The SELECT Statement is:
datTable = new DataTable();
fullStatementColumn = Convert.ToString(columnElements[0]);
String selectStatement = "SELECT [" + form1.colBox.Text + "]
FROM [" + form1.tableNameVal.Text + "]
WHERE convert(varchar(120),[" + form1.getColumnName() + "])='"
+ fullStatementColumn + "'";
I am attempting to dynamically update a set of database tables. I have two variables;
table_name & field_name. These are populated by a foreach loop, that loops through a DataTable. Everytime we hit a new row in the DataTable the names change respectively. Within this loop I create a new Oracle Connection and attempt to write an update with the current table_name/field_name. But Oracle keeps giving me an error on my ExcecuteNonQuery command.
Any help is greatly appreciated!!
EDIT: I have reformatted to include parameters, still does not work does anyone have any ideas on what I am doing wrong?
foreach (DataRow fieldtable in setofTables.Tables[0].Rows)
{
//do work
table_name = fieldtable["table_name"].ToString().Trim();
field_name = fieldtable["field_name"].ToString().Trim();
MessageBox.Show(table_name + field_name);
//create parameters
OracleParameter fieldParamater = new OracleParameter("field_name", OracleDbType.Varchar2);
OracleParameter diffParameter = new OracleParameter("mark_diff_oracle", OracleDbType.BinaryFloat);
OracleParameter wellIdParameter = new OracleParameter("id", OracleDbType.Char);
//wellIdParameter.Size = 10;
//create oracle connection and open
OracleConnection OrclCon2 = new OracleConnection("Data Source=" + dbname + "; User Id=" + userid + ";Password=" + password1 + ";");
OrclCon2.Open();
//prepare sql to be passed to oracle
string UpdateOraSQL = "UPDATE " +table_name+ " set :field_name = :field_name - (:mark_diff_oracle) where id = ':id' and :field_name is not null;";
MessageBox.Show(UpdateOraSQL);
//create dommand
OracleCommand UpdateDB = new OracleCommand(UpdateOraSQL, OrclCon2);
UpdateDB.CommandType = CommandType.Text;
//add parameters
UpdateDB.Parameters.Clear();
UpdateDB.Prepare();
UpdateDB.Parameters.Add(fieldParamater).Value = field_name;
UpdateDB.Parameters.Add(diffParameter).Value = mark_diff_oracle;
UpdateDB.Parameters.Add(wellIdParameter).Value = id;
Remove the semicolon from the end of the sql statement. Change the following code
string UpdateOraSQL = "UPDATE " +table_name+ " set :field_name = :field_name - (:mark_diff_oracle) where id = ':id' and :field_name is not null;";
to
string UpdateOraSQL = "UPDATE " +table_name+ " set :field_name = :field_name - (:mark_diff_oracle) where id = ':id' and :field_name is not null";
See the following link for more information
why the semicolon couldn't place in the CommandText of a OracleCommand when C#
If the problem is still not resolved, it might be helpful if you post the entire exception message also.
AFAIK, you cannot use parameters to define the column that you're updating.
AFAIK, you can only use parameters for the values that you'd want to set.
So, you'll have to create the query using string concat:
string sql = "UPDATE " + tableName + " SET " + fieldName + " = :p_Value WHERE id = :p_Id";
OracleCommand UpdateDB = new OracleCommand(sql, OrclCon2);
UpdateDB.Parameters.Add ("p_Value", ... ).Value = "foo";
UpdateDB.Parameters.Add ("p_Id", ...).Value = 4;
Offcourse, you should make sure that the variables you're adding to the string do not contain any harmfull statements. You should do sanity checks on them.
Perhaps, you can even verify if the tableName or the fieldName that has been passed, is a valid / existing tableName/columnname.
In SQL, one does not say COLUMN <> NULL. The proper syntax is COLUMN IS NOT NULL.
I am trying to perform dynamic sql select where I am selecting from a table using a parameter.
SELECT null FROM #TableName
However I am getting error must declare table variable #TableName. I suspect this is because I am selecting from a table using a variable. I have not needed to do this before.
List<SqlParameter> sqlParams = new List<SqlParameter>()
{
new SqlParameter("TableName", "testtable"),
new SqlParameter("FieldName", "testfield"),
new SqlParameter("Find", "testfind"),
};
string sqlSelect = "SELECT null FROM #TableName
WHERE #FieldName LIKE '%' + #Find + '%' ";
DataTable dtSelect = SqlHelper.ExecuteDataset(sqlConn, CommandType.Text,
sqlSelect, 30, sqlParams.ToArray()).Tables[0];
//30 = timeout
How can I perform the above using dynamic sql? (no stored procedures please)
You cannot use parameters for things like table and column names. For those you could have a whitelist of possible values and then use string concatenation when building the SQL query.
You can't use parameters like that, so you have to build the query as a string. You could do that in SQL, but you can also just create the string in the C# code.
Make sure that the table name and field name are safe and trusted values, and doesn't come directly from an unsafe source like a web request.
string tableName = "testtable";
string fieldName = "testfield";
List<SqlParameter> sqlParams = new List<SqlParameter>() {
new SqlParameter("Find", "testfind"),
};
string sqlSelect =
"SELECT null " +
"FROM " + tableName + " " +
"WHERE " + fieldName + " LIKE '%' + #Find + '%' ";
private DataTable ExecuteDynamic(string TableName,string FieldName, string Find)
{
string sqlSelect = "SELECT * FROM " + TableName +
" WHERE " + FieldName + " LIKE '%'" + Find + "'%' ";
using (connection = new SqlConnection(Strcon))
connection.Open();
{
using (cmd = new SqlCommand(sqlSelect, connection))
{
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 60;
adpt = new SqlDataAdapter(cmd);
dt = new DataTable();
adpt.Fill(dt);
return (dt);
}
}
}
Copy table content to another table in the same database with C#.
I got one database (Baza) with some data in two tables NEW and OLD. I need to periodically move NEW data to OLD data table (after I do some measuring). I need to compare these data in next step.
I'm using SQL Server CE wit Baza.sdf file. In any sophisticated way to copy table to table do it (some loop doing it automatically)?
Thanks
I solved it in this way:
Program reads in loop table NEW row by row and each value changes to parameter. I got 8 columns so 8 parameters(7 integers and one string)
Next each of parameter is inserted to OLD table.
Resuld is also displayed in textBox1:
SqlCeConnection conn = new SqlCeConnection("Data Source = \\Program Files\\My Program\\Program.sdf; Password ='mypassword'");
conn.Open();
try
{
SqlCeCommand cmd = new SqlCeCommand("SELECT * FROM [NEW]", conn);
SqlCeDataReader rdr = cmd.ExecuteReader();
cmd.Connection = conn;
cmd.ExecuteNonQuery();
while (rdr.Read())
{
int param1 = rdr.GetInt32(0);
int param2 = rdr.GetInt32(1);
int param3 = rdr.GetInt32(2);
int param4 = rdr.GetInt32(3);
int param5 = rdr.GetInt32(4);
int param6 = rdr.GetInt32(5);
int param7 = rdr.GetInt32(6);
string param8 = rdr.GetString(7);
textBox1.AppendText(" " + param1 + " " + param2 + " " + param3 + " " + param4 + " " + param5 + " " + param6 + " " + param7 + " " + param8);
textBox1.AppendText(System.Environment.NewLine);
SqlCeCommand ins = new SqlCeCommand("insert into [OLD] values ('" + param1 + "','" + param2 + "','" + param3 + "','" + param4 + "','" + param5 + "','" + param6 + "','" + param7 + "','" + param8 + "');");
ins.Connection = conn;
ins.ExecuteNonQuery();
}
}
catch (Exception msg)
{
MessageBox.Show(msg.ToString());
}
conn.Close();
What's wrong with:
insert into [table] (field1, field2)
select field1, field2 from [table2] where (your conditions are met)
? :-)
Since that's not supported in CE, thanks #marc_s, you could get the records from the NEW table using a select, then insert them into the OLD table, and then loop through the initial recordset to delete the rows from the NEW by ID for example.
Adding to what CodeCaster stated,
Put his code in a storedprocedure and create a job to run on a set interval of your choosing.
You can add logic to the storedprocedure to check the validity of the data as well and set it to notify you if the data was incorrect. Examples could be given if you included a more specific information in your question.