I have this Oracle 11g table
CREATE TABLE "DBNAME"."CANDIDATES"
(
"ID" NUMBER(24,0),
"USRINS" VARCHAR2(30 CHAR),
"DATINS" DATE,
"USRUPD" VARCHAR2(30 CHAR),
"DATUPD" DATE,
"EXM_ID" NUMBER(24,0),
"TYPE" NUMBER(3,0),
"PSN_ID" NUMBER(24,0),
"KOD" NUMBER(20,0),
"STATUS" NUMBER(20,0),
"PRICINA" VARCHAR2(200 CHAR)
)
Now i have this command in C#
string insertIntoCandidates = "INSERT INTO CANDIDATES " &
"(USRINS, DATINS, PSN_ID, KOD, STATUS, PRICINA) " &
values ("
+ ":usrins, "
+ ":datins, "
+ ":psn_id, "
+ ":kod, "
+ ":status, "
+ ":pricina"
+ ") ";
command.Parameters.Add(":usrins", null);
command.Parameters.Add(":datins", DateTime.Now);
command.Parameters.Add(":psn_id", getPsnIDByEMBG(result.embg));
command.Parameters.Add(":kod", result.kod_kandidat);
if (result.status)
{
command.Parameters.Add(":status", 1);
}
else
{
command.Parameters.Add(":status", 0);
}
command.Parameters.Add(":pricina", result.pricina);
int res = command.ExecuteNonQuery();
The columns for which I don't insert a value, can get null values.
After executing the last line, I get am exception ORA-01722: invalid number. I tried looking for an answer, but without any luck. Could you help me out? Thanks
add
command.BindByName=true;
apparently Oracle defaults to positional binding instead of name binding.
An ORA-01722 ("invalid number") error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a valid number. So, check the parameters for correct data types.
And also see:
C# parameterized queries for Oracle - serious & dangerous bug!
and
Why am I getting an ORA-01722 (invalid number)?
Further to michaos's answer, also note that it doesn't matter what you name your parameters, they have to be added in the order in which they appear in the query. If not, then you can get misleading ORA-01722 (and other) errors. Yes this is a horrible bug!
Instead of null you have to use DBNull.Value
Related
I'm trying to make a search bar that searches in the Access database table with multiple criteria.
When I type in the search bar a number it will do the search just fine, but when I delete what's in the search bar it shows me this error:
System.Data.SyntaxErrorException:
'Syntax error: Missing operand after '=' operator.'
And when I type a character it shows me this error:
'System.Data.EvaluateException: 'Cannot find column [a].'
Note:
the Chamber field is type number, long integer.
Here is the code:
private void ResSearchtextBox_TextChanged(object sender, Eventers e)
{
Data View dv = dt.DefaultView;
dv.RowFilter = "(Name LIKE'%" + ResSearch_textBox.Text + "%') OR (Surname LIKE'%" + ResSearch_textBox.Text + "%') OR (Chamber =" + ResSearch_textBox.Text + ")";
ResDGV.DataSource = dv;
}
What I've tried:
private void ResSearchtextBox_TextChanged(object sender, EventArgs e)
{
DataView dv = dt.DefaultView;
dv.RowFilter = "(Name LIKE'%" + ResSearch_textBox.Text + "%') OR (Surname LIKE'%" + ResSearch_textBox.Text + "%') OR (Chamber ='" + ResSearch_textBox.Text + "')";
ResDGV.DataSource = dv;
}
The issue you're seeing is because the RowFilter property expects a string in the format of an SQL WHERE clause, and you are trying to use it to filter based on the value in the ResSearch_textBox control. When the text box is empty, the RowFilter property is being set to "(Name LIKE'%%') OR (Surname LIKE'%%') OR (Chamber =)", which is causing the error you mentioned. When you type a character in the text box, the RowFilter property is being set to "(Name LIKE'%a%') OR (Surname LIKE'%a%') OR (Chamber ='a')", which is causing the second error you mentioned.
To fix these issues, you can add some logic to your code to handle the case where the text box is empty. One way to do this is to check the length of the text in the text box, and only apply the filter if the length is greater than 0. You can also use the TryParse method to try converting the text in the text box to a number, and only apply the Chamber = filter if the conversion is successful.
If there is no value in ResSearch_textBox, the formatted row filter will be, in part, ...OR (Chamber =) in the first case,and ...OR (Chamber = ''), in the second. The first is invalid SQL, as the error indicates. The second might be a database error, because if the Chamber field is expected to be a number, ’’ can’t be converted to one. The solution depends on what you want to happen if there is no chamber filter. If you don’t want to do the query at all, you could add code to the handler to skip the query if there’s no value. You could also substitute a default value — 0, maybe? — instead of a blank.
The error is pretty clear, then the value of the textbox is empty in that case it becomes something like (Name LIKE'%%') OR (Surname LIKE'%%') OR (Chamber =) and hence there is no value after = that is why you are seeing the Syntax error: Missing operand after '=' operator.' error.
your second error looks related to the datatype.
when you have only an a character in that case RowFilter is trying to compare with the string value but the Chamber datatype is different.
so you should add a check like before this code if (searchText == "" || add other checks here) { return; }
I am writing Insurance Managment System as project at University.
This is my MySQL commadn:
string lifeQuery = "insert into lifeinsurance values( null, '" + surname.Text + "." + pesel.Text + "', " + double.Parse(lifeInsSumTB.Text) + ", '" + double.Parse(lifeInsPriceTB.Text)
+ ");";
But te problem is that in UWP double is with ',' and to MySQL i need to have it with '.'.
When I try to do this like this: '25,453' it says data truncated. Without ' ', like this 25,453 it says that column count doesn't match value count at row 1, because it interets it as two different values 25 and 453.
So my question is:
How do I insert this double value to my table?
This problem is caused by the implicit conversion to a string when you call double.Parse and then concatenate the result back into the sql text. This requires the compiler to represent the double value as a string and it will use the current culture to do the conversion. Of course the result is not what MySql expect to be a double value.
Moreover using string concatenation to build sql commands leads to Sql Injection hacks. A very nasty problem that you should avoid. Always.
So let's try to add some code to resolve these problems
// A parameterized string without any concatenation from user input
string lifeQuery = #"insert into lifeinsurance
values( null, #surname, #sum, #price)";
MySqlCommand cmd = new MySqlCommand(lifeQuery, connection);
// Add the parameters with value for each placeholder in string
cmd.Parameters.AddWithValue("#surname", surname.Text + "." + pesel.Text);
// Parse the user input as a double using the current culture to correctly
// interpret the comma as decimal separator.
// Note that here I have no check on the correctness of the input. If your
// user cannot be trusted to type a valid double number then you should use
// the double.TryParse approach separating these lines from the actual check
cmd.Parameters.AddWithValue("#sum", double.Parse(lifeInsSumTB.Text, CultureInfo.CurrentCulture));
cmd.Parameters.AddWithValue("#price", double.Parse(lifeInsPriceTB.Text, CultureInfo.CurrentCulture));
cmd.ExecuteNonQuery();
Like other said - there are better ways to send over data with Sql. That being said this answer focuses on addressing your specific problem.
I think your problem may be your language/culture settings.
Try this:
Console.WriteLine(double.Parse("19.2323244").ToString("G", CultureInfo.InvariantCulture));
Output:
19.2323244
https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo?view=netcore-3.1#Invariant
When I update a field in my MySQL database, it always adds a whitespace to the value.
I tried to remove the whitespace with the trim-command and the replace-command. Neither of them worked. So I expect that it isn't a whitespace but some vague ASCII character. These are the commands I used:
this.foo = result.GetValue(0).ToString().Trim();
this.bar = result.GetValue(0).ToString().Replace(" ","");
The field it updates is a VARCHAR(xx). This is my MySQL update command:
MySqlCommand cmd = new MySqlCommand("UPDATE " + table + " SET " + new_field + " =' " + new_value+ "' WHERE " + field+ "= " + value + "",this.con);
this.con is my connection to the MySQL database.
FYI: I use .NET 3.5CF with a mysql.data.cf DLL in Visual Studio 2008.
Could someone help me out with this problem? It's driving me nuts.
Well yes, you've got a leading space in the SQL:
"UPDATE " + table + " SET " + new_field + " =' " + new_value+ "'
Note the bit straight after "=" - you've got a quote, then a space, then new_value.
However, you shouldn't be putting the values in the SQL directly in the first place - you should be using parameterized SQL statements... currently you've got a SQL injection attack waiting to happen, as well as potential problems for honest values with quotes in.
You should use parameterized SQL for both new_value and value here... I'm assuming that field and table come from more "trusted" sources?
This appears to have a space where the * is
" ='*" + new_value
I'm getting a weird issue with substringing. Apparently the string I get can't be cast into an Int32 for some odd reason. The error message I get when I try doing that is "input string is not in correct format". Because of this, I can't insert these values into the Database either.
Here's the code...
string width = GetMetadata(filename, 162); //returns "1280 pixels"
string height = GetMetadata(filename, 164); //returns "700 pixels"
width = width.Substring(0, width.IndexOf(' ')); //returns "1280"
height = height.Substring(0, height.IndexOf(' ')); //returns "700"
//test: "System.Convert.ToInt32(width)" will fail, giving error "input string was not in correct format"
//doing the above on "width" yields the same result
//fails, giving error "no such column: 1280" (underlying database is sqlite)
Database.NonQuery("INSERT INTO image VALUES (" + fileid + ", " + width + ", " + height + ")");
For all the normal reasons - primarily avoiding leaving data conversions to the database, and preventing SQL injection attacks - I would suggest that you perform the parsing to a number in C#, and then use a parameterized query to talk to SQLite.
In this case, that will make it a lot easier to debug - either .NET will fail to parse the string as well (in which case it's likely to be a problem with your data) or it will work, and you won't need to worry about what conversions database was performing.
EDIT: I've just seen your comment saying that Convert.ToInt32 fails as well. That's a pretty clear indication that it's the data which is causing a problem.
I'd expect your code to look something like this:
string widthText = GetMetadata(filename, 162);
string heightText = GetMetadata(filename, 164);
widthText = width.Substring(0, width.IndexOf(' ')).Trim();
heightText = height.Substring(0, height.IndexOf(' ')).Trim();
int width = int.Parse(widthText, CulutureInfo.InvariantCulture);
int height = int.Parse(widthText, CulutureInfo.InvariantCulture);
using (SQLiteCommand cmd = Database.CreateCommand())
{
cmd.CommandText = "INSERT INTO image VALUES (?, ?, ?)";
cmd.Parameters.Add(fileid);
cmd.Parameters.Add(width);
cmd.Parameters.Add(height);
cmd.ExecuteNonQuery();
}
Note that the Trim call will remove any leading spaces, which it seems was the cause of the problem.
There may be some stray whitespaces in the string variables width and height. Invoke Trim() method on the strings before casting them into integers:
width = width.Trim();
height = height.Trim();
Hope this helps. Let us know.
The question is simple.
I have a column in my database of data type NVARCHAR(20) .. so when I try to enter a data in this column that's for example contains 22 characters, it just ignores the last 2 characters instead of Throwing an exception!
Is this is normal ? .. and how to secure the database from such an issue ?
P.S: Of course I use validation controls and server validation, but how do I secure the database, is there's some kind of an advanced constraint more than just specifying the column's length, so it throws an exception and not accept the entered date ??
Edit
try
{
using (SqlConnection conn = new SqlConnection(ConnStr))
{
string Command = "SET NOCOUNT ON; INSERT INTO [Countries] (CountryName, IsVisible) VALUES (#Name, #IsVisible);";
using (SqlCommand comm = new SqlCommand(Command, conn))
{
comm.Parameters.Add("#Name", System.Data.SqlDbType.NVarChar, 20);
comm.Parameters["#Name"].Value = Name;
comm.Parameters.Add("#IsVisible", System.Data.SqlDbType.Bit);
comm.Parameters["#IsVisible"].Value = IsVisible;
conn.Open();
comm.ExecuteNonQuery();
return "Successfully added " + Name + " to the countries.";
}
}
}
catch (SqlException SqlEx)
{
string ErrorMessage = "";
for (int i = 0; i < SqlEx.Errors.Count; i++)
{
ErrorMessage += SqlEx.Errors[i].Number + " : " + SqlEx.Errors[i].Message + "\n";
}
return ErrorMessage;
}
Well this is the the code I'm using, and btw I just tried to insert a bigger data than the column's length directly from the Sql Management Studio and it actually displayed the message you were just describing!
The problem is between these two lines.
comm.Parameters.Add("#Name", System.Data.SqlDbType.NVarChar, 20);
comm.Parameters["#Name"].Value = Name;
SQL Server NEVER gets to see more than 20 chars. .Net is doing the truncation.
I can't remember the documentation for SQLParameter, a Google search was faster.
http://www.eggheadcafe.com/software/aspnet/30873895/sqlparameter-question.aspx
Now if you DID specify the SqlParam's length to be 40, then .NET will
automatically truncate the string to 40 characters for you.. and no
error will be raised (but you may loose data and not know it).
There are several areas that will truncate the data prior to it reaching the table without generating errors.
As #Richard pointed out for your specific case it is being truncated by ADO.
If you called a stored procedure that had a varchar(20) parameter and passed it 22 characters of data, the parameter processing engine in SQL server would truncate it as well.
However, if you wrote an insert state that tried to directly stuff 22 characters into a varchar(20) column, then you would see the error.
Basically, the parameter processing piece is silently "fixing" it. Whereas if you get rid of the parameters then it will fail. Which is why this question really is an exact duplicate of the one #gbs referenced.
Obviously, getting rid of the parameters is FAR from ideal.