I'm having problems with some code I'm trying to write. I'm doing something for suppliers orders, so I have a table which is named "encomendas_fornecedores" with a autoincrement field before the key that is the code of sale which consists in a EF before the number(which is a text field).
Here is the code:
connection.Open();
OleDbCommand comando1 = new OleDbCommand();
OleDbCommand comando2 = new OleDbCommand();
OleDbCommand comando3 = new OleDbCommand();
comando1.Connection = connection;
comando2.Connection = connection;
comando3.Connection = connection;
comando1.CommandText = "INSERT INTO encomendas_fornecedores (cod_encomenda_forn, cod_metodo, cod_forn, total_pagar_forn) VALUES('FO', '" + txtcodmetodo.Text + "', '" + txtcodforn.Text + "', '" + lbltotalapagar.Text + "'); ";// insert into table the values with a FO to cod
comando1.ExecuteNonQuery();
comando2.CommandText = "Select MAX(num_encomenda) From encomendas_fornecedores;";// selecting maximum num encomenda so I can isolate it and add to a text before(btw I do this in php/sql no problems
int numero = Convert.ToInt32(comando2.ExecuteScalar());//max num_encomenda
string codencomendaforn= "EF"+Convert.ToString(numero);// sales code completed
comando3.CommandText = "UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = '"+ numero +"';";//query that is giving me the problems, it says something like "type of data incorrect in data expression"
comando3.ExecuteScalar();//giving me error this line
connection.Close();
But now here's the catch the cod_encomenda_forn is text and the num_encomenda auto increment as it is in the sql, and I tried to show the query in a textbox to see if its anything is wrong but nothing seems wrong.
"UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = **'**"+ **numero** +"**'**;";//query that is giving me the problems,it says something like "type of data incorrect in data expression"
You are passing a string numero to a where statement that seems like it is expecting a number. As long as it is numeric it should work, but definitely not gauranteed to work. Second you are passing anothercodencomendaforn string to encomenda what is encomenda 's data type?
It appears that you are not handling potential datatype differences between your c# code and your SQL query. In addition single quoting '' around a value in a SQL statement tells the database engines that it is a string even if that is '1234'. While SQL will automatically convert some values it doesn't always. In addition c# .net library also looks for some conversion etc. before sending the SQL statement. To fix appropriately use parameters that are data typed to the database type in the SQL table. To fix it simply in the statement figure out your data types and fix the '' single quotes appropriately.
PS the people trying to help you in the comments were being nice and telling you the professional way of keeping your job in the future when you graduate after fixing this issue.
Related
Ok been starring at this for a good while and i can not under stand why it is not updating my database..... I do not get an error messages it runs just fine. Code below
if (e.KeyCode == Keys.Enter)
{
// #WORK
string searchtext = txtAssetScanned.Text;
string searchcmd = "UPDATE " + lstCompCode.SelectedItem.ToString() + " SET " + lstCompCode.SelectedItem.ToString() + ".[Inventory Status]= \"FOUND\" WHERE [Inventory number] like '*" + searchtext + "';";
MessageBox.Show(searchcmd);
myConnection.Open();
OleDbCommand search = new OleDbCommand();
search.Connection = myConnection;
search.CommandText = searchcmd;
search.ExecuteNonQuery();
myConnection.Close();
}
There are a few things that pop out here :
Use Parameterized Queries. You should be using parameterized queries, concatenating in the manner you currently are can cause syntax issues and leave you vulnerable to SQL Injection.
Consider Using Single Quotes for Values. When setting string values in SQL, you should use single quotes 'value' as opposed to double quotes (i.e. "value").
SelectedValue over SelectedItem. Consider using the SelectedValue property as opposed to SelectedItem.ToString() to ensure you use the proper value.
Table Names as Parameters May Not Be Allowed. If you are using a table name as a parameter, which in many cases may be flat out rejected (as they are generally reserved for values), so fair warning.
Double-check for Typos. Finally, ensure the properties that you are targeting are correct and do not contain any typos (i.e. Foo.[Inventory number], etc.)
You can apply these changes as follows :
using(var connection = new OleDbConnection("{your-connection-string}"))
{
// Build your query with parameters
var query = "UPDATE ? SET [Inventory Status] = 'FOUND' WHERE [Inventory number] LIKE ?";
using(var command = new OleDbCommand(query, connection))
{
connection.Open();
// Add your parameters
command.Parameters.AddWithValue("#table",lstCompCode.SelectedValue);
command.Parameters.AddWithValue("#search", "*" + txtAssetScanned.Text);
// Now that your queries are added, perform your update
command.ExecuteNonQuery();
}
}
The Likely Issue
As I mentioned, some databases will not allow you to pass in table names as parameters without resorting to stored procedures, dynamic SQL, etc. You may be better off simply defining the table that you want to use directly :
var query = "UPDATE [YourTableName] SET [Inventory Status] = 'FOUND' WHERE [Inventory number] LIKE ?";
Since you cannot pass this through via parameters, you might consider adding some logic to determine which to use and hard-code it along with some sanitation to avoid possible nefarious behavior.
I have a button which adds products to the invoice, I want it to delete products off the database as well, how can I edit this query so it deletes from the database?
I think my error is because of the way I am converting cmbQuantity.Text, can someone help me with a fix?
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - '" + Convert.ToInt32(cmbQuantity.Text) + "' WHERE productName='" + cmbProdName.Text + "'", con);
Without the error message, it's hard to guess.
But at first sight, you have a typo here : quantityAvailable=quantityAvailabe - should be quantityAvailable=quantityAvailab**l**e -.
Moreover, you must not quote the integer part, so '" + quantityToRemove + "' becomes " + quantityToRemove + ". But the best is to use parametrization, which will simplify your code. See Why do we always prefer using parameters in SQL statements?
Try to separate access to your UI and building your SQL:
int quantityToRemove = Convert.ToInt32(cmbQuantity.Text);
string productName = cmbProdName.Text;
string sqlUpdate = #"UPDATE Product
SET quantityAvailable = quantityAvailable - #quantityToRemove
WHERE productName= #productName";
SqlCommand inventorycontrol = new SqlCommand(sqlUpdate, con);
inventorycontrol .Parameters.AddWithValue("quantityToRemove", quantityToRemove);
inventorycontrol .Parameters.AddWithValue("productName", productName);
In the question you have not specify the error, but there may be chances of getting error in your code. that i will clarify you.
When it failed to convert the cmbQuantity.Text to int, you need not to pass an integer within double quotes :- Here my suggested answer will help you to handle this error by showing error message if the quantity is invalid.
The query you are using opens a wide range to SQL Injection. I suggest you to use parameterized query to avoid injection, As a whole you can use like the following:
int quantity;
if (int.TryParse(cmbQuantity.Text, out quantity))
{
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - #Quantity WHERE productName=#prodName", con);
inventorycontrol.Parameters.AddWithValue("#Quantity",quantity);
inventorycontrol.Parameters.AddWithValue("#prodName", cmbProdName.Text);
//Execue command here
}
else
{
// show message invalid quantity
}
I'm trying to execute a prepared sql query which updates CLOB fields in an Oracle 10g database (10.2.0.1).
If I execute the following query from inside SQL Developer and supply the values for the placeholders, there is no prblem. If I however execute it through an OracleCommand (Oracle.DataAccess.dll, version 1.102.0.1 (I think), .NET Framework 3.5),
I get the error message below. Note that we are not using the default oracle client as we require bulk insertion. The given ODP version and .NET Framework version are unfortunately a hard requirement and we may not change that.
Query:
UPDATE master_table
SET description = :description,
modification_notes = :modification_notes
WHERE master_id = :master_id;
Error:
ORA-00932: inconsistent datatypes: expected - got CLOB
Further Inormation:
Parameters are assigned as follows:
var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test";
I have tried the following things:
insert to_clob() into the SQL query
assign a Oracle.DataAccess.Types.OracleClob object to the parameter.
I have also found the following description, but I would really want to be able to keep the prepared query.
How to insert CLOB field in Oracle using C#
Is it possible to do this through a prepared query?
I've attached a complete example which produces the error. DESCRIPTION and MODIFICATION_NOTES are two columns of type CLOB in the database.
Input data:
connection: OracleConnection to the database
master_id: primary key to filter for
Code:
Disclaimer: I typed the following example by hand, there might be mistakes which are not in the actual code
var query = "UPDATE master_table " +
"SET description = :description " +
" modification_notes = :modification_notes " +
"WHERE master_id = :master_id";
var param_master_id = new OracleParameter(":master_id", OracleDbType.Int64);
param_master_id.Value = master_id;
var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test1";
var param_master_id = new OracleParameter(":modification_notes", OracleDbType.Clob);
param_description.Value = "Test2";
IDbCommand command = new OracleCommand(query, connection);
command.parameters.Add(param_master_id);
command.parameters.Add(param_description);
command.parameters.Add(param_modification_notes);
command.ExecuteNonQuery(); // this line throws an exception
You need to set this to true if you want to bind by name. Default is bind by the order of the parameter added.
cmd.BindByName = true;
Edit: My answer below applies for typical use of Clobs where the size is greater than 32k (what they were designed for). If you know you will always be binding less than 32k bytes, or 16k characters in the usual case of unicode you can bind as Varchar2 and free yourself from having to create a temporary lob.
--
Keep in mind that a LOB in an oracle column is really a LOB Locator, a pointer to the actual data. Before you can update a CLOB column with that Lob Locator, you need to create and populate a temporary CLOB first.
In the ODP.NET samples directory in your Oracle Home there should be a LOB directory, in there it looks like samples5.cs might be a good place to start. Here is a snippet from it:
// Set the command
OracleCommand cmd = new OracleCommand(
"update multimedia_tab set story = :1 where thekey = 1");
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
// Create an OracleClob object, specifying no caching and not a NCLOB
OracleClob clob = new OracleClob(con, false, false);
// Write data to the OracleClob object, clob, which is a temporary LOB
string str = "this is a new story";
clob.Write(str.ToCharArray(), 0, str.Length);
// Bind a parameter with OracleDbType.Clob
cmd.Parameters.Add("clobdata",
OracleDbType.Clob,
clob,
ParameterDirection.Input);
try
{
// Execute command
cmd.ExecuteNonQuery();
See the accepted answer for the actual solution.
[Edit: Former suspected answer]:
After several days of testing and debugging I found the solution which was so far away from everything I considered:
Apparently, you need to bind all Clob fields first before binding anything else - even when using actual placeholders instead of using :1, :2 etc.
Changing the bind order (i.e. the order of the AddParameter calls) fixed it.
Try This :
string Query3 = " DECLARE " +
"str varchar2(32767); " +
" BEGIN " +
" str := '" + base64ImageRepresentationLogo + "'; " +
" update map_general_settings set value=str where DESC_AR='LOGO_IMG' ; END; ";
command.CommandText = Query3;
command.ExecuteNonQuery();
I have the following code in asp.net:
using (OleDbCommand command = dbConnW.CreateCommand())
{
string CreateTableK = null;
CreateTableK += "Create Table DSKKAR00 (DSK_ID c(10),DSK_KIND N(1),MON_PYM C(3))";
OleDbCommand cmdCreateTable = new OleDbCommand(CreateTableK, dbConnW);
cmdCreateTable.ExecuteNonQuery();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(WorkRoomNo + ",");
sb.Append("1,");
sb.Append(",");
OleDbCommand cmd3 = new OleDbCommand("Insert into DSKKAR00 (DSK_ID,DSK_KIND,MON_PYM) Values (" + sb.ToString() + ")", dbConnW);
cmd3.ExecuteNonQuery();
But I have the following error:
Syntax error
In addition to what Chris has offered, you are starting your CREATE TABLE with a NULL string variable, then doing a += to it. From what I remember, a NULL += "anystring" will remain a null value... You might be crashing right there too.
Although VFP is not really suceptible to SQL Injection like other SQL engines, its good habit to do parameterizing. When you do, use "?" as a place-holder for the value you want to insert, and add parameters in the same order sequence as the "?" represent.
string CreateTableK =
"Create Table DSKKAR00 (DSK_ID c(10),DSK_KIND N(1),MON_PYM C(3))";
OleDbCommand cmdCreateTable = new OleDbCommand(CreateTableK, dbConnW);
cmdCreateTable.ExecuteNonQuery();
string MyInsert =
"insert into DSKKAR00 ( dsk_id, dsk_kind, mon_pym ) values ( ?, ?, ? )";
OleDbCommand cmd3 = new OleDbCommand( MyInsert, dbConnW);
cmd3.Parameters.AddWithValue( "parmSlot1", WorkRoomNo );
cmd3.Parameters.AddWithValue( "parmSlot2", 1);
cmd3.Parameters.AddWithValue( "parmSlot3", 'tst' ); // or whatever variable to put
cmd3.ExecuteNonQuery();
First off, any time you have an error it's usually best to post the entire error message you get.
Also, when trying to debug a query problem, you should emit the actual query being sent to your server/database and inspect it. This way you can find various problems like too many commas.
Speaking of which, looking at your code, you are concatenating a String and it really looks like you have way too many commas.
The emitted query looks like it will be:
insert into DSKKAR00(DSK_ID, DSK_KIND, MON_PYM) VALUES( X,1, ,)
where X is the value of your WorkRoomNo variable.
Obviously, that isn't valid syntax and would result in the error you've seen. The commas indicate there are 4 values being passed, but the insert query only identifies 3 columns.
The next issue has to do with the column definitions themselves. The first column of that table is a c(10); the third is a c(3). I'm a little rusty, but aren't those character fields?
If so then you need to adjust your string builder to add the appropriate quotes around the values...
Which leads us to the final problem: Don't use String concatentation to build queries. Use Parameterized queries
I'm a newb here, and it may be because I've been up since yesterday morning, but I can't find my error here in this insert statement. My handler asked me not to parameterize for this training project (it won't be deployed), so no worries for the injection vulnerabilities. Anyway, the query's right, the data types are correct, and the table and field names are spelled correctly. What am I missing here? And is there a better way to find it than just staring at the screen until it comes to you?
protected void BtnSubmit_Click(object sender, EventArgs e)
{
string x = Request.QueryString["SubId"];
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string comQuery = "INSERT INTO Submission (Status, StatusComment, StatusValue) VALUES ('" + "decline" + "', '" + TbComments.Text + "', 2) WHERE SubmissionId =" + x;
using (SqlConnection sqlConn = new SqlConnection(connectionString))
{
sqlConn.Open();
using (SqlCommand comCmd = new SqlCommand(comQuery, sqlConn))
{
comCmd.ExecuteNonQuery();
}
}
}
An INSERT can't have a WHERE clause. It makes no sense to have one, you're putting data in, not narrowing it down.
If you're trying to change preexisting data, that's an UPDATE, not an INSERT. Here's an example:
"UPDATE Submission
SET Status='decline', StatusComment='" + TbComments.Text + "', StatusValue = 2
WHERE SubmissionId = " + x
That is incorrect INSERT syntax. Correct INSERT syntax is:
INSERT INTO tableName (columnList) VALUES (valueList)
columnList and valueList must have same count of items and values must be of type expected by columns.
or
INSERT INTO tableName (columnList)
SELECT columnList2
FROM tableName2
WHERE conditionsFromTable2
columnList and columnList2 must have same count of items of same types. You can use any complicated select joined over multiple tables with condition applied on data from these tables.
You need to use UPDATE, not INSERT
INSERT insert new row, therefore WHERE makes no sense
Where clause is not allowed in Insert query. Form your code I guess that you need to use Update query.
You'r trying to INSERT INTO Submission data from TbComments. So you need to SELECT the data from TbComments and then INSERT INTO Submission
string comQuery =
"INSERT INTO Submission (
Status,
StatusComment,
StatusValue)
SELECT
'decline',
TbComments.Text,
2)
FROM TbComments
WHERE SubmissionId =" + x;
So your SQL statement is:
"INSERT INTO Submission (Status, StatusComment, StatusValue) VALUES (blah) WHERE SubmissionId =" + x;
The problem is definitely the WHERE. WHERE isn't valid for INSERT - See the MSDN documentation for the Insert command. Since you're filtering by SubmissionId, you probably want to do an UPDATE instead.
As for a better way of finding the problem, learning to use the MSDN documentation is a good step. A quick Google search for "msdn t-sql insert" will give you the page I linked to earlier in this answer. Documentation, experience, Google and Stack Overflow. That's how you find solutions :)