Return multiple values from a SELECT query - c#

For example i have a database called dbuser:
username: teste
password: xxxx
isonline: 1
username: teste2
password: xxxx
isonline: 1
I thought that this query:
"SELECT username FROM dbuser WHERE (isonline ='1')"
would return both teste and teste2, but when i ask the result for example in a MessageBox, with both teste and teste2 online, it only shows teste, but when i close the teste connection then it appears teste2 in the MessageBox. Im guessing its only returning the first row to me, so how can i get all the values?
This is the method code:
public static string GetOnline()
{
string listaOnline;
listaOnline = ExecuteQuery("SELECT * username FROM dbuser WHERE (isonline ='1')").ToString();
return listaOnline;
}
and I show it as MessageBox.Show(DbManager.GetOnline());

This should give you a list of strings that you want in the fastest manner. reader.GetString(0) means that you take a sting value from column with index 0 (so the first one).
List<string> result = new List<string>();
using (SqlConnection connection = new SqlConnection(databaseConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.CommandType = CommandType.Text;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader.GetString(0));
}
reader.Close();
}
command.Cancel();
}
}
return result;

Try something like the following, create a class for users:
[Table(Name = "foo")]
public class Users
{
[Column(Name = "user_name")]
username {get; set;};
[Column(Name = "user_pword")]
password {get; set;};
[Column(Name = "user_isonline")]
isonline {get; set;};
}
public static List<Users> GetOnline()
{
List<Users> listaOnline = new List<Users>();
listaOnline = ExecuteQuery("SELECT * username FROM dbuser WHERE (isonline ='1')");
return listaOnline;
}

You can do something like this, it is just outline of the code, will give you some hint(need to add some spaces/ special characters to between names).
string user = string.Empty;
foreach (var item in DbManager.GetOnline())
{
user += item;
}
MessageBox.Show(user);
Hope it will help..
Also you can do it in the following way:
List<string> listUser= new List<string>();
listUser =DbManager.GetOnline();
string users= string.Join(",", listUser.ToArray());
MessageBox.Show(users);
In this way Username will be printed separated by ",".

Related

Display 2 SQL tables using c#

I am trying to display two SQL tables from the same DB in a webpage but the code below is displaying the 'BottomStock' table twice and everything I try seems to either get part of the data from the 'TopStock' table or none at all. I have scroll through countless forums but I have been unable to find a suitable solution. Any help would be appreciated.
public class Test4Model : PageModel
{
public List<FreezerInfo> listTopFreezer = new List<FreezerInfo>();
public List<FreezerInfo> listBottomFreezer = new List<FreezerInfo>();
public void OnGet()
{
try
{
using (var connection = new SqlConnection("Data Source=SDS-
LAPTOP\\SQLEXPRESS;Initial Catalog=test;user id=sa;password=wis09"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM TopStock";
command.ExecuteNonQuery();
command.CommandText = "SELECT * FROM BottomStock";
command.ExecuteNonQuery();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
//reader.Read();
{
FreezerInfo TopStock = new FreezerInfo();
TopStock.Description = reader.GetString(1);
TopStock.Quantity = reader.GetString(2);
listTopFreezer.Add(TopStock);
FreezerInfo BottomStock = new FreezerInfo();
BottomStock.Description = reader.GetString(1);
BottomStock.Quantity = reader.GetString(2);
listBottomFreezer.Add(BottomStock);
}
}
}
}
}
catch (Exception ex)
{
}
}
}
public class FreezerInfo
{
public string Description { get; set; }
public string Quantity { get; set; }
}
You are using SqlCommand completely wrong. ExecuteNonQuery does not return results. Only ExecuteScalar or ExecuteReader do. Furthermore, you have two batches each with a SELECT, but you are only executing one and somehow expecting the results to be interleaved.
I would advise you to use one batch of two SELECT statements, you can use NextResult to move to the next resultset within the batch.
Store your connection string in a settings file, not hard-coded.
Only select the columns you need, rather than SELECT *.
Use column names rather than ordinals, especially if you are using SELECT *.
Do not swallow exceptions. Handle them or allow them to bubble back to the caller.
Consider using async to allow the caller to continue asynchronously.
Reconsider the data types of the columns.
Consider why you have two almost identical tables in the first place. Perhaps they should be merged.
public void OnGet()
{
try
{
const string query = #"
SELECT Description, Quantity
FROM TopStock;
SELECT Description, Quantity
FROM BottomStock;
";
using var connection = new SqlConnection(connectionStringFromSettingsFileHere);
using var command = new SqlCommand(query, connection);
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
while (reader.Read())
{
FreezerInfo TopStock = new FreezerInfo
{
Description = (string)reader["Description"],
Quantity = (string)reader["Quantity"], // shouldn't it be an int???
};
listTopFreezer.Add(TopStock);
}
reader.NextResult();
while (reader.Read())
{
FreezerInfo BottomStock = new FreezerInfo
{
Description = (string)reader["Description"];
Quantity = (string)reader["Quantity"], // shouldn't it be an int???
};
listBottomFreezer.Add(BottomStock);
}
}
catch (Exception ex)
{
// exception handling here. DO NOT SWALLOW
}
}

Populating list from Database - System.InvalidCastException

I have a simple class that I want to populate a list of from a database:
class Foreman
{
public int ForeBadge { get; set; }
public string ForeName { get; set; }
}
Heres my method that is supposed to return a list of Foreman objects:
static public List<Foreman> getForeman()
{
connectionString.DataSource = "server";
connectionString.InitialCatalog = "db";
connectionString.UserID = "tunnelld";
connectionString.Password = "pw";
string queryString = "SELECT * FROM [QTRAXAdmin].[vwQT_Foreman]";
List<Foreman> list;
// Creates a SQL connection
using (var connection = new SqlConnection(connectionString.ToString()))
{
using (var command = new SqlCommand(queryString, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
list = new List<Foreman>();
while (reader.Read())
list.Add(new Foreman { ForeBadge = reader.GetInt32(0), ForeName = reader.GetString(1) });
}
}
connection.Close();
return list;
}
The method is erroring out at list.Add(new Foreman { ForeBadge = reader.GetInt32(0), ForeName = reader.GetString(1) });
with: An unhandled exception of type 'System.InvalidCastException' occurred in System.Data.dll
To me it looks like I'm using the correct variable types. What am I doing wrong?
Try using the field names explicitly in your query to ensure columns are coming back in the order you think they are. That is the most suspicious thing I see. Alternatively you could use column names in your using block. And of course double check the column definition in the database.
Assuming the table column names are forebadge and forename, replace:
string queryString = "SELECT * FROM [QTRAXAdmin].[vwQT_Foreman]";
with:
string queryString = "SELECT FOREBADGE, FORENAME FROM [QTRAXAdmin].[vwQT_Foreman]";

c# sqlite query

C# SQLite Query
String sql = #"SELECT user FROM '" + channel + "' ORDER BY currency DESC LIMIT 10";
You have a problem with your query. The SELECT extracts only one column from the table represented by the variable channel. So your GetString(1) in the reader loop fails because there is no field at index 1 (arrays start at index zero). You need to change that GetString index.
Then there is a problem in the return value. You say that you want to return a single string but there is no return statement and you don't have any single string to return
You could write
public string top10()
{
List<string> toplist = new List<string>();
String sql = "SELECT user FROM '" + channel + "' ORDER BY currency DESC LIMIT 10";
using (cmd = new SQLiteCommand(sql, myDB))
{
using (SQLiteDataReader r = cmd.ExecuteReader())
{
while (r.Read())
{
toplist.Add(r.GetString(0));
}
}
}
return string.Join(",", toplist);
}
or change the return type of the method to
public List<string> top10()
{
.....
return toplist;
}
or to
public string[] top10()
{
.....
return toplist.ToArray();
}
I have changed your internal array to a List<string> because if you have less than 10 records your array will have empty strings instead a list will return just the rows found.
You may also try this answer.
public string getTop10()
{
List<string> Toplist = new List<string>();
string connection = "YourConnectionString";
using (var con = new SQLiteConnection { ConnectionString = connection })
{
using (var command = new SQLiteCommand { Connection = con })
{
con.Open();
command.CommandText = #"SELECT user FROM #channel ORDER BY currency DESC LIMIT 10";
command.Parameters.AddWithValue("#channel", channel);
using (var r = command.ExecuteReader())
{
while(r.Read())
{
Toplist.Add(r.GetString(0));
}
}
}
}
return string.Join(",", Toplist);
}

Delete data from sql database not working

when you select items from the listbox, you want to delete selecteditems. Why doesnt it work when selected data removed from database? I must have missed something. I got error message
No mapping exists from object type.
This is a method parameter:
IsDelete = _dinnerRemover.RemoveDinners(lstDinner.SelectedItems);
This class is to delete data from database
public bool RemoveDinners(dynamic dinnerItems)
{
Dinners = new List<FoodInformation>();
using (var sqlConn = new SqlConnection(_sqlConnectionString))
{
const string sqlQuery = "delete from DinnerTemplates where Dinner = #dinner";
using (var command = new SqlCommand(sqlQuery, sqlConn))
{
try
{
//command.CommandType = CommandType.StoredProcedure;
//command.CommandText = "sp_dinner";
foreach (var item in dinnerItems)
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#dinner", item);
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
sqlConn.Close();
}
}
}
return Dinners;
}
If dinnerItems is a list of strings then say that, don't use dynamic unless you absolutely have to.
To delete a bunch of items, issue one sql query with an IN clause. Don't issue lots of individual queries.
Try this:
public int RemoveDinners(List<string> dinnerItems)
{
using (var sqlConn = new SqlConnection(_sqlConnectionString))
{
const string sqlQuery = "delete from DinnerTemplates where Dinner in ({0})";
using (var command = new SqlCommand())
{
var paramNames = new string[dinnerItems.Count];
int i = 0;
foreach (string item in dinnerItems)
{
string paramName = "#Dinner" + i;
command.Parameters.AddWithValue(paramName, item);
paramNames[i] = paramName;
i += 1;
}
command.CommandText = String.Format(sqlQuery, String.Join(",", paramNames));
command.Connection = sqlConn;
command.CommandType = CommandType.Text;
sqlConn.Open();
return command.ExecuteNonQuery();
}
}
}
You have to bear in mind that you kind of left out some really relevant code, like what is a DinnerItem, since you're getting the error on a line related to its type.
However, the reason you're getting that error is because item can't be marshaled to a type of something like string or int.
That's probably because item is likely a custom class. One option would be to override the ToString method of the class:
public override string ToString() {
// return some property value, or set of property values
// strung together here.
}
another option would be to send in the actual Property you want off of item when issuing AddWithValue.
You need to define SqlDbType for command's parameter.
don't use dynamic type,use string..
if i were you,i would rather
IsDelete = _dinnerRemover.RemoveDinners(lstDinner.SelectedItems.ToString());
change the parameter to :
public bool RemoveDinners(string dinnerItems)
and the query to :
const string sqlQuery = "delete from DinnerTemplates where Dinner = dinnerItems";

oledb retrieve entire record and return from .accdb

example of a return function that returns only string value, how do I return multiple values consisting of different data types in a single record by simply calling one function?
public static string selectPassword(string user)
{
using (var connection = new OleDbConnection(connectionString))
using (var command = connection.CreateCommand())
{
command.Parameters.AddWithValue("#user", user);
command.CommandText = "SELECT [Password] FROM [Password_Table] WHERE Password_ID = [#user]";
command.CommandType = CommandType.Text;
connection.Open();
var value = command.ExecuteScalar();
return value == DBNull.Value ? null : value.ToString();
}
}
my record would be searched by Participant_Name, and would need to return Participant_Name, Participant_ID, Address, Contact_Number & Gender fields, all consisting of string, integers etc..
Create a data-type which consists of fields and properties that are able to hold the information that you want to retrieve.
Populate an instance of that type in your method, and return it.
Something like this, for instance:
public class Participant
{
public int Id { get; private set; }
public string Name {get; set;}
public string Address {get; set; }
public Participant( int id, string name, string address )
{
this.Id = id;
this.Name = name;
this.Address = address;
}
}
public Participant GetParticipant( string name )
{
using( var conn = new OleDbConnection (connectionString) )
{
using( var cmd = connection.CreateCommand() )
{
command.CommandText = "SELECT [Id], [Name], [Address] FROM Participant WHERE [name] LIKE #p_name";
command.Parameters.Add ("#p_name", OleDbType.VarChar).Value = name + "%";
using( var reader = command.ExecuteReader() )
{
if( !reader.HasRows() ) return null;
reader.Read();
return new Participant (reader.GetString("Id"), reader.GetString("name"), reader.GetString("address"));
}
}
}
}
Note: there can be syntax errors, since I haven't pulled it through the compiler, but I think you'll catch the drift.
for your needs you should return a DataRow object or an object array which you can get by calling .ItemArray on a DataRow
what you need to change in your method above is to use a DataAdapter and call its Fill method to fill a DataTable then return the first row of such DataTable, if any row is present.
you could also do this with the DataReader but then you should construct the array or objects container to return by yourself... I think dataRow.ItemArray is faster to code.

Categories

Resources