List.Count always returns 0 - c#

I'm creating a public static List<> of variables (from MySQL query) but the List's Count always returns 0! I've tried everything so far but no success. Here is my code:
public static List<string> GetHashedVars(string ID)
{
List<string> lst = new List<string>();
MySqlConnection conn;
MySqlCommand cmd;
MySqlDataReader reader;
string connString, queryStr = "";
connString = ConfigurationManager.ConnectionStrings["GameserverConnString"].ToString();
using (conn = new MySqlConnection(connString))
{
//The query for execution
queryStr = "SELECT * FROM account.account WHERE id_hashed=?hid LIMIT 1";
//Open the connection to the database
conn.Open();
//execute command
cmd = new MySqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("?hid", ID);
using (reader = cmd.ExecuteReader())
{
//Loop through results
while (reader.Read())
{
lst.Add(reader.GetString(reader.GetOrdinal("id_hashed")));
lst.Add(reader.GetString(reader.GetOrdinal("login_hashed")));
lst.Add(reader.GetString(reader.GetOrdinal("webcode_hashed")));
lst.Add(Encryption.CipherEncryption(reader.GetString(reader.GetOrdinal("status")).Trim()));
}
}
reader.Close();
conn.Close();
}
queryStr = "";
reader = null;
cmd = null;
conn = null;
connString = "";
return lst;
}

Looks like you are using named parameters but do not set your parameters correctly.
? is used for non named parameters and # are used for named parameters. Since the database connector you are using does not support non named parameters you have to follow the convention using the # in your query. This will set the parameters by name rather than by index.
queryStr = "SELECT * FROM account.account WHERE id_hashed=#hid LIMIT 1";
...
cmd.Parameters.AddWithValue("#hid", ID);
Explanation from msdn.
The Microsoft .NET Framework Data Provider for SQL Server does not
support the question mark (?) placeholder for passing parameters to a
SQL Statement or a stored procedure called by a command of
CommandType.Text. In this case, named parameters must be used.

Related

Why does my MySQL connection not work in visual studio code C#?

i am making a program in visual studio code with C#, it is a paid program so it needs an hwid system. Basically i want it to check if your computer HWID exists in the HWID table in my users database. But it says it can't connect to the database. Can you help me? This is my code.`
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
MySqlConnection mydbCon = new MySqlConnection(connectionString);
mydbCon.Open();
MySqlCommand command = mydbCon.CreateCommand();
command.CommandText = "SELECT * FROM yourTable WHERE hwid = GetHDDSerial";
IDataReader reader = command.ExecuteReader();
`
It could be that the connection string isn't formatted the way the MySQL connector wants it. The MySQL documentation shows "uid" instead of User, and "pwd" instead of Password. https://dev.mysql.com/doc/connector-net/en/connector-net-programming-connecting-connection-string.html
This should do what you need:
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand())
{
string sql = "SELECT * FROM yourTable WHERE hwid = #val1";
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = sql;
command.Parameters.AddWithValue("#val1", "GetHDDSerial");
connection.Open();
using (MySqlDataAdapter adapter = new MySqlDataAdapter())
{
using (DataSet ds = new DataSet())
{
adapter.SelectCommand = command;
adapter.Fill(ds);
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
// Do something here. You can access the data like this:
// row["Id"] or whatever your field names are.
// int id = (int) row["Id"];
// Of course, I don't know your field names, so you'll have to complete this.
}
}
}
}
}
}

Parameter SQL in C# doesn't work

I have this code and it does not work. Does anyone know why?
It did not return any data, but if run the query in SQL Server it returns the data.
using (SqlConnection connection = new SqlConnection(_dbContext.GetConnectionString()))
{
using (SqlCommand command = new SqlCommand())
{
StringBuilder stringQuery = new StringBuilder();
stringQuery.Append(" SELECT cd_material, ds_material");
stringQuery.Append(" FROM tbl_materiais");
stringQuery.Append(" WHERE ds_material like #Name");
command.Parameters.AddWithValue("#Name", "%" + name + "%");
command.CommandText = stringQuery.ToString();
command.CommandType = System.Data.CommandType.Text;
command.Connection = connection;
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
_product = new ProductSell();
((IProduct)_product).ID = reader.GetFieldValue<int>(0);
((IProduct)_product).Name = reader.GetFieldValue<string>(1);
listProduct.ToList<IProduct>().Add(_product);
}
}
}
}
What is listProduct and why do you call its ToList<>()?
listProduct.ToList<IProduct>() returns a new instance of List<IProduct> that is forgotten after this line executes. Calling .Add(_product) on this returned list does not affect listProduct.
My problem stay here
while (reader.Read())
{
DoSomething();
}
reader.Read() never is read, my table is simple, have only attributes: cd_material(int), ds_material(varchar). And Exception not are triggered.
This query :
SELECT cd_material, ds_material FROM tbl_materiais WHERE ds_material = '%produto%'
Many rows are returned if in owner database ( sql management)

How do I retrieve the values of a single column from a database table?

I have a table where I am trying to capture all the values in one column across many rows with a matching identifier. For example my query is similar to:
SELECT
prevHours
FROM
submissions
WHERE
projectCat='Capacity'
I am then trying to pass all of the values in prevHours into a single array that I can perform operations on.
The simplest way to work with a list of values from the database is to use a List<T>; the code is similar to what you have now, see below.
The code is quite simple:
var container = new List<int>();
var dbConnection = "...";
var query = "SELECT [prevHours] FROM [submissions] WHERE [projCat] = #Value";
using(var connection = new SqlConnection(dbConnection))
using(var command = new SqlCommand(query, connection))
{
connection.Open();
command.Parameters.Add("#Value", SqlDbType.VarChar, max).Value = "Capacity";
using(var reader = command.ExecuteReader())
while(reader.Read())
{
if(reader["prevHours"] != DBNull.Value)
container.Add(Convert.ToInt32(reader["prevHours"]));
}
}
Additionally, if you are not using the list for further processing, you could use ExecuteScalar and a query of the form
SELECT SUM(prevHours) FROM submissions WHERE projCat = #Value
for similar results using command.ExecuteScalar()
I write a function to return a database table:
public static DataTable ExecuteDataTable(SqlConnection conn, string cmdText,
params SqlParameter[] parameters)
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
}`

How to parameterise table name in ODBC query

I have an ODBC connection to a database and I would like the user to be able to view data within any table. As this is an ASP.net application I cannot trust that the table name sent doesn't also contain nasties. I have tried using a parameterised query but I always get an error saying that I "Must declare the table variable" - this appears to be an issue because it is the table name
string sql = "SELECT TOP 10 * FROM ? ";
OdbcCommand command = new OdbcCommand(sql, dbConnection);
command.Parameters.Add(new OdbcParameter("#table", tableName));
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(tableData);
What is the best method to achieve this in a secure way?
Use a stored procedure, it's the safest way.
Some hints:
You probably may also use the System.Data.SqlClient namespace objects
Enclose your connection, command and adapter objects initializations in using statements
Here's a simple example:
string sqlStoredProcedure = "SelectFromTable";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
using (OdbcCommand command = new OdbcCommand(sqlStoredProcedure, dbConnection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new OdbcParameter("#table", tableName));
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
Another way to go would be to retrieve all table names and validate the tableName string variable as an entry in the list, maybe using:
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
Here's a simple implementation based on your scenario:
string sql = "SELECT TOP 10 * FROM {0}";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
var matches = tables.Select(String.Format("TABLE_NAME = '{0}'", tableName));
//check if table exists
if (matches.Count() > 0)
{
using (OdbcCommand command = new OdbcCommand(String.Format(sql, tableName), dbConnection))
{
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
else
{
//handle invalid value
}
}

How to use executeReader() method to retrieve the value of just one cell

I need to execute the following command and pass the result to a label. I don't know how can i do it using Reader. Someone can give me a hand?
String sql = "SELECT * FROM learer WHERE learer.id = " + index;
SqlCommand cmd = new SqlCommand(sql,conn);
learerLabel.Text = (String) cmd.ExecuteReader();
As you can see i create the SQL statement and i execute it, but it does not work. Why?
The console says:
Cannot implicitly SqlDataReader to
String...
How can i get the desired results as String so the label can display it properly.
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT * FROM learer WHERE id = #id";
cmd.Parameters.AddWithValue("#id", index);
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
learerLabel.Text = reader.GetString(reader.GetOrdinal("somecolumn"))
}
}
}
It is not recommended to use DataReader and Command.ExecuteReader to get just one value from the database. Instead, you should use Command.ExecuteScalar as following:
String sql = "SELECT ColumnNumber FROM learer WHERE learer.id = " + index;
SqlCommand cmd = new SqlCommand(sql,conn);
learerLabel.Text = (String) cmd.ExecuteScalar();
Here is more information about Connecting to database and managing data.
ExecuteScalar() is what you need here
Duplicate question which basically says use ExecuteScalar() instead.

Categories

Resources