Could you please assist me, I am trying to fill a combobox with values from a column in a SQL Server table. I have tried various methods, but none of them returned the desired result.
The error is:
Error CS1503 Argument 1: cannot convert from 'string' to 'int'
This is my code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
fillCombo();
}
void fillCombo()
{
string con = "Data Source = xxxxx; Initial Catalog = xxxxx; Integrated Security = False; User Id = xxxxx; Password=xxxx;MultipleActiveResultSets=True";
string Query = "select * from LEAVE ;";
SqlConnection conDataBase = new SqlConnection(con);
SqlCommand cmd = new SqlCommand(Query, conDataBase);
SqlDataReader dr;
try
{
conDataBase.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
string lveName = dr.GetString("lve_name");
lveType.Items.Add(lveName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I would do this instead:
Dictionary<int, string> lveNames = new Dictionary<int, string>();
while (dr.Read())
{
string lveName = dr["lve_name"].ToString();
int lveId = int.Parse(dr["lve_id"].ToString());
lveNames.Add(lveId, lveName);
}
lveType.DataSource = new BindingSource(lveNames, null);
lveType.DisplayMember = "lveName";
lveType.ValueMember = "lveId";
Assuming that you have id lve_id.
DisplayMember and ValueMember are used to bind the label and id to the combo box.
Always look at the signatures of the methods you are trying to use:
dr.GetString(int)
You are trying to call
dr.GetString(string)
but there's not overloaded method that accepts a string. See the documentation of GetString().
Instead, GetString requires you to pass the zero based ordinal of the column you are trying to get the string from. Let's say lve_name is the second column in your query (a bit hard to tell, since you are using SELECT * FROM, but that's another topic), you have to use it like this:
string lveName = dr.GetString(1);
Also, check what the documentation has to say:
No conversions are performed; therefore, the data retrieved must already be a string.
This means, if your query returns anything other than a string, the method will most likely throw an InvalidCastException. To prevent that from happening, you have to edit your query, like for example
SELECT lve_id, CAST(lve_name as varchar) FROM LEAVE
Another possible solution would be to access the column like this:
string lveName = dr["lve_name"].ToString()
Related
This question already has answers here:
"Input string was not in a correct format" when converting to an int
(2 answers)
Closed 10 months ago.
I am attempting to search my database with a stored procedure via my program. The goal is for it to search using any of the three criteria entered. ID#, Firstname, and/or Lastname. I created the following stored procedure in MySql:
CREATE DEFINER=`mainuser`#`localhost` PROCEDURE `searchvisitor`(
enteredid int,
enteredfn varchar(25),
enteredln varchar(25)
)
begin
select visitors.visitorid, visitors.firstname, visitors.lastname, visitors.middleinitial from visitors where visitors.visitorid = enteredid or visitors.firstname like '%enteredfn%' or visitors.lastname like '%enteredln%';
end
My C# code is as follows:
the Database Query:
public DataView searchUserQuery(int id, string fn, string ln)
{
using (MySqlConnection conn = new MySqlConnection(Helper.connVal("ntpantry")))
{
conn.Open();
DataTable dt = new DataTable();
string lgquery = "searchvisitor";
MySqlCommand cmd = new MySqlCommand(lgquery, conn);
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("enteredid", id);
cmd.Parameters.AddWithValue("enteredfn", fn);
cmd.Parameters.AddWithValue("enteredln", ln);
MySqlDataReader dr = cmd.ExecuteReader();
dt.Load(dr);
DataView dv = new DataView(dt);
return dv;
}
}
The bridgeing query (to try edit or remove extra logic in one place):
public DataView Searchvisitor()
{
if (GetVisitor.VisitorFirstName.Length == 0)
{
GetVisitor.VisitorFirstName = " ";
}
if (GetVisitor.VisitorLastName.Length == 0)
{
GetVisitor.VisitorLastName = " ";
}
return dq.searchUserQuery(Convert.ToInt32(GetVisitor.VisitorID), GetVisitor.VisitorFirstName, GetVisitor.VisitorLastName);
}
And the call after hitting the search button:
private void button2_Click(object sender, EventArgs e)
{
//Add get set to put logic in bridge data instead
GetVisitor.VisitorID = Convert.ToInt32(textBox_searchid.Text);
GetVisitor.VisitorFirstName = textBox_searchfn.Text;
GetVisitor.VisitorLastName = textBox_searchln.Text;
data_searchresults.DataSource = bd.Searchvisitor();
DataGridViewColumn columnid = data_searchresults.Columns[0];
columnid.Width = 40;
DataGridViewColumn columnfn = data_searchresults.Columns[1];
columnfn.Width = 60;
DataGridViewColumn columnln = data_searchresults.Columns[2];
columnln.Width = 60;
//was currently working on fixing search results. works for id but not first name or last name. Also results box only shows 2 items
}
And in case needed, here are my properties used:
public class GetVisitor
{
public static int VisitorID { get; set; }
public static string VisitorFirstName { get; set;}
public static string VisitorLastName { get; set;}
}
When searching for the ID it works great! but if i try and just search the firstname and or lastname i get the following error:
System.FormatException: 'Input string was not in a correct format.'
My thoughts are that the names are null causing it to have format issues on whatever is left blank so I tried to entered a space to add something but it did not work. Does it go back to how my stored procedure is set up or is it in the C# code? I tried at it for a while and am having trouble.
Thanks in advance!
There's almost certainly a whole lot of irrelevant information in that question. This almost certainly has nothing to do with databases or queries or anything other than converting a string to a number. You didn't even tell us where the exception was thrown but I'm guessing that it's here:
GetVisitor.VisitorID = Convert.ToInt32(textBox_searchid.Text);
If that TextBox doesn't contain a valid representation of a 32-bit integer then that code will fail with that error message. The obvious solution is to validate the user input BEFORE converting it to a number. It is a TextBox after all, so the user might enter anything.
I would suggest that you first test whether the user has entered anything at all. If they haven't then you can assume that they're not trying to search by ID and proceed accordingly. How you do that is up to you but I would do it quite differently. That's beyond the scope of this question though. If they have entered something then you should check whether it's a valid number and stop if it's not. Only if it is should you proceed. The TryParse method of any numerical type (and a few others besides) can do the validation and conversion in a single step, e.g.
if (textBox_searchid.TextLength == 0)
{
// No ID entered
}
else if (int.TryParse(textBox_searchid.Text, out var id))
{
// Use id here
}
else
{
// Invalid ID entered
}
When I try out this query
select Category,ItemName,ItemBrand,ItemLocation,Qty,Date ,+'0000'+convert (varchar, ItemId)
as testing from Inventory in my SSMS . It works fine.
When I use the query in c# window form it will show error
Error Unable to cast object of type 'System.Int32' to type 'System. String'
private void databaseLoading()
{
query = "select Category,ItemName,ItemBrand,ItemLocation,Qty,Date ,+'0000'+convert (varchar, ItemId) as testing from Inventory";
//query = "select * from Inventory";
exeQuery = new SqlCommand(query, sqlconn);
try
{
sqlconn.Open();
// must close after use and less memory use
sqlReader = exeQuery.ExecuteReader();
while (sqlReader.Read())
{
string Catg = sqlReader.GetString(1).ToString();
string Name = sqlReader.GetString(2).ToString();
string Brand = sqlReader.GetString(3).ToString();
string location = sqlReader.GetString(4).ToString();
cbxCatg.Items.Add(Catg);
cbxItemName.Items.Add(Name);
cbxBrand.Items.Add(Brand);
cbxLocation.Items.Add(location);
}
sqlconn.Close();
sqlconn.Open();
// dataadapter it may auto close connection but it need more memory cause it will load all information to the table
sqlAdp = new SqlDataAdapter(exeQuery);
sqlAdp.Fill(dt);
dgvInventory.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
If a type of a column in sql server is int, then you should use GetInt32() in the reader, not GetString().
In addition, your first select item is a category query = "select Category, so in the reader the string Catg must have index 0 GetString(0)
One of your database column might be int.
Use:
sqlReader.GetInt32(1).ToString()
instead
I create an application using c# , In my authentification interface , i have a test control , i want to know profile user .
My database contains table named user which contains 4 columns
(id_user,name ,mail, profile)
Here is my code
public string profil_user(string login)
{
SqlConnection conn = new database().connect_user();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select profile from user where name = '" + login + "';";
SqlDataReader s = cmd.ExecuteReader();
if (s.Read())
{
return ( s.GetString(3));
}
else{return ("false"); }
}
but i have an exception in s.GetString(3)
system.IndexOutOfRange : index was outside the bounds of the array
You're only selecting a single field (profile) but then you're trying to select the 4th field (index 3) here:
return ( s.GetString(3));
In addition to just returning s.GetString(0) I would strongly advise you to:
Use parameterized SQL - always do this, to prevent SQL injection attacks, make your code more readable, and prevent unexpected text conversion problems
Either throw an exception or return null if the profile isn't found, instead of returning the string "false"
Use using statements for disposable things like SqlCommand, SqlConnection and SqlDataReader to ensure that you clean up resources appropriately
Start following .NET naming conventions to make your code more idiomatic
So something like:
public string GetUserProfile(string login)
{
string sql = select profile from user where name = #login";
// I assume Connect() returns an *open* connection?
using (var conn = new Database().Connect())
{
using (var command = new SqlCommand(sql, conn))
{
command.Parameters.Add("#login", SqlDbType.NVarChar).Value = login;
using (var reader = command.ExecuteReader())
{
// If it's an error (code failure) for there to be no matching profile,
// you may want to throw an exception instead.
return s.Read() ? s.GetString(0) : null;
}
}
}
}
So you want the fourth row, not the fourth column which you try to access with s.GetString(3):
int rowNum = 0;
while(s.Read())
{
if(++rowNum == 4)
{
return s.GetString(0);
}
}
return "false";
However, it is a bit strange to access the fourth row when you don't use an Order By. You should also only return the row that you want with the correct sql query.
You are also open for sql injection if you use string concatenation here:
cmd.CommandText = "select profile from user where name = '" + login + "';";
Use sql parameters:
cmd.CommandText = "select profile from user where name = #login";
cmd.Parameters.Add("#login", SqlDbType.VarChar).Value = login;
have 4 columns not rows
Ok, so you instead want the fourth column. Why don't you use the name instead?
Since you only select the profile-column(the fourth), you could simply use GetString(0). But you could also select all columns and then determine the correct index with GetOrdinal:
int profileColumnIndex = s.GetOrdinal("profile");
return s.GetString(profileColumnIndex);
This is useful if you don't control the query or it might be changed in future.
You are selecting only 1 field, thus index 3 is out of bounds. It also very important to Use parameters. Try:
cmd.CommandText = "select profile from user where name = #login;";
cmd.Parameters.Add("#login, SqlDbType.NVarChar).Value = login;
SqlDataReader s = cmd.ExecuteReader();
while (s.Read())
{
return s[0].ToString();
}
The parameter for SqlDataReader.GetString should be the column index. You're only selecting one column so you get an exception.
Because you do not have all the fields in your select list
Change the SQL to:
select id_user,name ,mail, profile from user where name = '" + login + "';
I have a combox called comboBox2 and i want to fill this combobox with a column named 'Stud_Name' of my database table called 'Student_Table'
I use the following code:
void Fillcombo()
{
string constring = "Data Source=(LocalDB)\\v11.0;AttachDbFilename=C:\\ChaCha\\ChaCha\\chacha.mdf;Integrated Security=False";
string query = "select * from database.Student_Table";
SqlConnection condb = new SqlConnection(constring);
SqlCommand cmddb = new SqlCommand(query, condb);
SqlDataReader myreader;
try
{
condb.Open();
myreader = cmddb.ExecuteReader();
while(myreader.Read())
{
string sName = myreader.GetString("Stud_Name");
comboBox2.Items.Add(sName);
}
}
catch (Exception ex)
{
}
}
But, I am getting an error message like this:
The best overloaded method match for
'System.Data.Common.DbDataReader.GetString(int)' has some invalid
arguments.
How can I remove this error?
I use Visual Studio 2012.
Error message is clearly says;
There is no overload of SqlDataReader.GetString method that takes string as a parameter.
This method takes int as a parameter which is the number of zero-based column that you want to get.
You need to put as an integer value which is Stud_Name column number in your query.
For example; if your Stud_Name is the first column of your query, you can use it like;
string sName = myreader.GetString(0);
Also use using statement to dispose your SqlConnection, SqlCommand and SqlDataReader.
Your problem is the parameter you pass to the method called GetString. Uou should pass there the index of the column, you want to read from. Instead of doing this, you pass the name of the column. That's why you get this error message.
For more documentation, please have a look here.
After the query execution the result I need to take is UserNames part.
I'm gettting an error: Cannot apply indexing with [] to an expression of type 'method group'
public class ProcessInput
{
string connectionString = (string)ConfigurationSettings.AppSettings["myConString"];
private string msg_arr;
string username = null;
private void MooseSeenInput(string MobileNo, string Date, string odd, params Array[] msg_arr)
{
SqlConnection conn = new SqlConnection(myConString);
conn.Open();
SqlCommand com = new SqlCommand("SELECT * FROM Users as users WHERE UserName=#UserName AND State!='1' AND State!='4'", conn);
com.Parameters.AddWithValue("#UserName", UserName);
// com.ExecuteNonQuery();
using (SqlDataReader reader = com.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
String UserNames = (reader.Read["users"]);
}
}
}
}
}
Error occurred at line:
String UserNames = (reader.Read["users"]);
Use
String UserNames = reader.GetString(0);
And as #leppie pointed in its comment, you could also use the field name as indexer
So supposing the field is named users you could also write this:
String UserNames = reader["users"].ToString();
Your error is a compiler error as you were trying to apply index syntax onto a method call, which in C# involves brackets.
The SqlDataReader does expose an indexer, but it is on the reader itself, not a method member:
string username = (string)reader["users"];
This is how I tend to style this code:
using (SqlDataReader reader = com.ExecuteReader())
{
int userOrd = reader.GetOrdinal("users");
while (reader.Read())
{
string username = reader.GetString(userOrd);
}
}
Note that I ask the reader for the ordinal prior to iterating an unknown number of records. This is good for two reasons:
I have cached the ordinal once and use it many times, this helps performance.
I have not hard-coded the ordinal so if someone were to change the column position in the result-set in the stored procedure / script, my code would continue to work.
Pretty sure you just wanna do:
String UserNames = reader["users"] as string;
String UserNames;
if(reader["users"]!=null)
UserNames = (string)reader["users"];//or reader["users"].ToString();