I have noticed a strange behavior while building parameters for a stored procedure I call. Within a table used there's a column that has the type VARCHAR(16). When I build the parameter for this column my first instinct was to do it like this:
ret = new SqlParameter();
ret.ParameterName = name;
ret.Value = (string)value;
This approach gave me an error saying String or binary data would be truncated.
The method that works is when I build the parameter as such:
ret = new SqlParameter(name, type, length);
ret.ParameterName = name;
ret.Value = (string)value;
The interesting thing is that when I set a length for a varchar parameter, if the value is an empty string, the stored procedure will go on without a hitch. When I however put a singe letter or more in the value field, the same error appears.
My questions are why it accepts a parameter that is null or empty with an incorrect declaration of length, and what is the minimal info you have to give a parameter in c# so that it will be passed correctly?
Related
at line 161,I want to insert my text in parameter t,but it won't change when i debug it.although the parameter tmp had alredy changed.
I want to change this Text in UI,when my parameter t changes.
With respect to your specific issue, Insert is defined as:
public string Insert (int startIndex, string value);
and returns a new string. In C#, strings aren't modified, new strings are created. In this way, they act like a value type, even though they're a reference type. In other words, once a string is created, it is never modified - it's 'immutable'. So, you need to store your newly created string.
In cases like this, I like to use the string interpolation, as it allows me to get a slightly clearer representation of what the final string will look like.
var tmp = System.Text.Encoding.UTF8.GetString ( e.Message );
t.text = $"{tmp}\n{t.text}"; // Note that a newline is represented as \n
Or, if you add the System.Text namespace; you could reduce it down to:
using System.Text;
...
t.text = $"{Encoding.UTF8.GetString ( e.Message )}\n{t.text}";
The string type in c# is immutable, therefore Insert returns a new string instead of modifying the current one.
Do:
t = t.text.Insert(0, tmp + "//n");
See also
How to modify string contents in C#
Imagine this code:
string value = "1.23";
string query = "UPDATE MYTABLE SET COL1=#p1";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("#p1", value);
cmd.ExecuteNonQuery();
On my database it will work with value="1.23" if COL1 is decimal type column. But it will fail if value is "1,23" (comma instead of a dot as a decimal point). The error is
Error converting data type nvarchar to numeric
I'd like it to work in both cases with "value" being a string variable.
Unfortunately I cannot just replace comma for the dot as this code is going to be more universal, dealing both with numeric and varchar columns
Is there any way that an query accepts a parameter with number written as a string both with dot and a comma and correctly puts it in into table?
Thanks for any help
If the value isn't semantically a string, you shouldn't send it as a string. The type of the parameter value is important, and influences how it is transmitted and can lead to culture issues (comma vs dot, etc).
If the value is semantically a decimal, then use something like:
string value = "1.23";
var typedValue = decimal.Parse(value); // possible specifying a culture-info
//...
cmd.Parameters.AddWithValue("#p1", typedValue);
Then it should work reliably.
Unrelated, but you can make ADO.NET a lot easier with tools like "Dapper":
connection.Execute("UPDATE MYTABLE SET COL1=#typedValue", new { typedValue });
I am running into the following problem. I don't know what i'm doing wrong. It shows me an error "The best overloaded method match for 'System.Data.Common.DbDataReader.GetString(int)' has some invalid arguments."
Here is my code:
SqlDataReader myReader;
mycon.Open();
myReader = cmdDatabase.ExecuteReader();
while (myReader.Read())
{
string cName = myReader.GetString("C_Name");
textBox2.Text=cName;
}
The GetString method only accepts an int. You're passing it a string.
From MSDN, the parameter (an integer) represents "the zero-based column ordinal."
If C_Name is the first column (for example), you'd want to call:
string cName = myReader.GetString(0);
As has been mentioned several times now, the signature of GetString requires an integer representing the column index. You can translate the column name to its ordinal position using GetOrdinal.
Therefore, you can get the string value of the "C_NAME" column by using myReader.GetString(myReader.GetOrdinal("C_NAME")).
SqlDataReader also overrides the indexer, which lets you write the same as (string)myReader["C_Name"]
Complete example:
var sqc = new SqlCommand("SELECT C_NAME from table", con);
using (var reader = sqc.ExecuteReader())
{
while (reader.Read())
{
int ordinal = reader.GetOrdinal("C_NAME");
string byOrdinal = reader.GetString(ordinal);
string byIndexer = (string)reader["C_NAME"];
Console.Writeline("Column {0}, has the value of {1} (which is the same as {2})",
ordinal, byOrdinal, byIndexer);
}
}
You should also be careful to wrap your readers in using statements to ensure you don't leak database connections or run into a case where you consider enabling MARS.
Look at the signature of GetString():
System.Data.Common.DbDataReader.GetString(int)
It takes an integer ordinal (i.e. zero-based position) and you are trying to pass a string. There are no overloads which take a single string parameter.
As the error indicates, you are trying to use an overload of the GetString which does not exist.
You are passing a string argument, while the method is expecting an integer that represents the index of the requested column.
You can read more about the method in the dcumetnation
Try changing your code to something like:
int indexOf cNameIdx = 5;// replace this with the real index from your select query
string cName = myReader.GetString(cNameIdx );
Here is my code within my ASP.net project. I am trying to store some values into my object with my web form, but it pops up an error message saying: Cannot implicitly convert type 'short' to 'string'.
textbox.Text = Convert.ToInt16(object.number);
lstbox.SelectedValue = Convert.ToInt16(object.ID);
Within my object class, I have declared my variables to int. Please let me know what is wrong.
The Text and SelectedValue properties are strings. Why would you convert the values to short in the first place?
textbox.Text = object.number.ToString();
lstbox.SelectedValue = object.ID.ToString();
You can't assign non-string values to a property which accepts string/text values. In your case, you are trying to assign a short value to text property of textbox. Please cast the value to string using Convert.ToString or ToString().
So your code should be
textbox.Text = Convert.ToString(object.number);
or
textbox.Text = object.number.ToString();
Scenario is same while assigning the selected value property of listbox.
lstbox.SelectedValue = Convert.ToString(object.ID);
Since you want to pass the value to the object, you should have the object's variables = the input value.
object.number = Convert.ToInt16(textbox.Text);
object.ID = Convert.ToInt16(lstbox.SelectedValue);
DataRow drEmpty = dsResult.Tables[1].NewRow();
dsResult.Tables[1].Rows.InsertAt(drEmpty, 0);
DataRow drBranch = dsResult.Tables[1].Rows[1];
drBranch[1] = "Branch"; <--error
dsResult.Tables[1].Rows.InsertAt(drBranch, 1);
my expected output for this few line of code is to add first empty row data into my dropdownlistbox and second row by adding "Branch" into the it but i failed to do so
Error msg given --
Input string was not in a correct format.Couldn't store in ows_ID Column. Expected type is Int64.
after that i try to change to
drBranch[1] = int64.Parse("Branch");
and i get another error
second error msg -- Input string was not in a correct format.
i get the answer that i want already, i will post the answer after 7 hours ,thanks all
In you example drBranch[1] represents the ows_ID column, which only accepts values of type integer. That means only numbers without a decimal point are allowed.
You could convert strings that contain numbers like "55" to an integer using Int64.Parse("55"), but you can't convert strings like "Branch" to integer. You're trying to store a string in the ows_ID column. Maybe you're trying to access the wrong index?
The problem is that "Branch" is not integer.
To cast a value into integer you need an integer value as a string like "526", "100".
I assume you think that the column ordinal is one-based but it's zero-based, hence drBranch[1] is the second column.
In my opinion it's better to use the column's name instead:
drBranch.SetField<String>("Branch", newBranch);
(i'm using the SetField extension method since it's strongly typed and supports nullables)
I would suggest using a DataTable before using DataRow:
DataTabel dtResult = dsResult.Tables[1].Clone();
dtResult.Columns[1].DataType = Type.GetType("System.String");
DataRow drEmpty = dtResult.NewRow();
dsResult.Tables[1].Rows.InsertAt(drEmpty, 0);
DataRow drBranch = dsResult.Tables[1].Rows[1];
drBranch[1] = "Branch";
dsResult.Tables[1].Rows.InsertAt(drBranch, 1);