Why am I getting "Invalid Cast Exception" with this SQLite code? - c#

I've got this code to get a count from a SQLite table:
internal static bool TableExistsAndIsNotEmpty(string tableName)
{
int count;
string qry = String.Format("SELECT COUNT(*) FROM {0}", tableName);
using (SQLiteConnection con = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
con.Open();
SQLiteCommand cmd = new SQLiteCommand(qry, con);
count = (int)cmd.ExecuteScalar();
}
return count > 0;
}
When it runs, I get, "Invalid Cast Exception"
As is probably obvious, the value being returned from the query is an int, that is to say the count of records (I get "2" when I run the query, namely "SELECT COUNT(*) FROM WorkTables" in Sqlite Browser).
So what is being invalidly cast here?
As a sort of a side note, I know it's better to use query parameters, and I found out how to do this in a Windows Store App here [How can I use SQLite query parameters in a WinRT app?, but don't know how to do it in an oldfangled (Windows Forms/Windows CE) app.
I would think it would be something like this:
string qry = "SELECT COUNT(*) FROM ?";
using (SQLiteConnection con = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
con.Open();
SQLiteCommand cmd = new SQLiteCommand(con);
count = cmd.ExecuteScalar(qry, tableName);
}
...but nothing of the ilk that I tried compiled.

In this context the ExecuteScalar returns a System.Int64.
Applying the (int) cast creates the exception you are seeing
object result = cmd.ExecuteScalar();
Console.WriteLine(result.GetType()); // System.Int64
You could solve your problem with Convert.ToInt32
SQLiteCommand cmd = new SQLiteCommand(qry, con);
count = Convert.ToInt32(cmd.ExecuteScalar());

Related

Query result will into an int or a string

string komut = "SELECT Count FROM servers WHERE id = 1";
MySqlDataAdapter da = new MySqlDataAdapter(komut, baglanti);
int result = da;
My codes like this I want that : "SELECT Count FROM Server WHERE id = 1" query's result will transfer into result varuable.
How can i do that ? Thank you.
To properly accomplish such a goal:
var query = "SELECT COUNT(*) AS Rows FROM [Table] WHERE Id = #Id";
You would do that to prevent Syntax Query Language (SQL) Injection. Once you have your query defined, you would:
private readonly string dbConnection;
private const string query = "SELECT COUNT(*) AS Rows FROM [Table] WHERE Id = #Id";
int? rows;
using(SqlConnection connection = new SqlConnection(dbConnection))
using(SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
command.Parameters.Add("#Id", SqlDbType.Int).Value = id;
// command.Parameters.AddWithValue("#Id", id); // Another approach.
using(SqlDataReader reader = command.ExecuteReader())
if(reader.Read())
rows = reader["Rows"] as int?;
}
That should return an integer of the valid row count.
Important: The int? will allow a null to be returned if the cast to an integer fails. Rather then throw an Invalid Cast Exception. Secondly, a bulk of the data is wrapped in a using which will implement the IDisposable method to free up resources.
The rest should be relatively straight forward.
sql query is not valid.
count function need a param like count(*)

How to define a limit as parameter?

Given conn is an OdbcConnection object and count is an int, how would I use count as parameter for my query?
...
var query = conn.CreateCommand();
query.CommandText = "select top ? * from players order by Points desc";
query.Parameters.Add("top", OdbcType.Int).Value = count;
var reader = query.ExecuteReader();
while (reader.Read())
{
...
}
...
This way I get a syntax error ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '#P1'.
If it is not possible the way I tried how would I do it the correct way instead?
You can also use SET ROWCOUNT the advantage is you can use a integer as parameter and avoid dynamic queries.
SET ROWCOUNT #top;
select * from table;
SET ROWCOUNT 0;
read the documentation
You can do:
query.CommandText = "select top (#topparameter) * from players order by Points desc";
query.Parameters.AddWithValue("#topparameter", count.ToString());
If you are using SqlServer then use SqlConnection and SqlCommand like:
using (SqlConnection conn = new SqlConnection("YourConnectionString"))
{
using (SqlCommand query = new SqlCommand("select top (#topparameter) * from players order by Points desc", conn))
{
query.Parameters.AddWithValue("#topparameter", count.ToString());
var reader = query.ExecuteReader();
while (reader.Read())
{
}
}
}

MySql get number of rows

I try to get number of rows from a table with this :
string commandLine = "SELECT COUNT(*) FROM client";
using (MySqlConnection connect = new MySqlConnection(connectionStringMySql))
using (MySqlCommand cmd = new MySqlCommand(commandLine, connect))
{
connect.Open();
int count = (int)cmd.ExecuteScalar();
return count;
}
And i get the exception:
Specified cast is not valid.
Any idea how i can fix it?
Try this
using (MySqlCommand cmd = new MySqlCommand(commandLine, connect))
{
connect.Open();
return Convert.ToInt32(cmd.ExecuteScalar());
}
using (MySqlCommand cmd = new MySqlCommand(commandLine, connect))
{
connect.Open();
return Convert.ToInt32(cmd.ExecuteScalar());
}
EDIT: Make also sure to handle exceptions in your code (E.g. if there is SQL Connection Error).
Also, if it's not a COUNT(*) the value returned by ExecuteScalar() can be null (!)
If you wish to use the cast, you can use:
long count = (long)cmd.ExecuteScalar();
As mentioned above, COUNT in MySql returns BIGINT, hence casting with an int fails.

SQL works on Oracle SQL Developer but won't works on C# code

I have this SQL that works if i just execute on Oracle SQL Developer:
SELECT * FROM MYTABLE
WHERE LOWER(TRANSLATE(DESCRIPTION, 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc'))
LIKE LOWER(TRANSLATE('%são paulo%', 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc'))
But when is execute on C# code, wont work. The result always is 0.
string translate = "'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc'";
string query = string.Format("SELECT * FROM {0}
WHERE LOWER(TRANSLATE(DESCSITE, {2}))
LIKE LOWER(TRANSLATE({1}, {2}))",
TABLE, string.Format("'%{0}%'", str.ToLower()), translate);
UPDATE
This is how show in the breakpoint:
SELECT * FROM PROD
WHERE TRANSLATE(LOWER(DESCSITE), 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc')
LIKE TRANSLATE(LOWER('%macarrão%'), 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc')
And the same problem. Works on Oracle SQL Developer bu wont on C# code.
UPDATE
I tried this, but but in this case is not working to.
string query = string.Format("SELECT * FROM {0}
WHERE LOWER(TRANSLATE(DESCSITE, {1}))
LIKE LOWER(TRANSLATE(:DESCSITE, {1}))", TABLE, translate);
List<OracleParameter> parameters = new List<OracleParameter>();
parameters.Add(new OracleParameter(":DESCSITE", string.Format("'%{0}%'", str)));
If I only try this, i know tha will work, but I have to check the others things.
string query = string.Format(#"SELECT * FROM {0} WHERE CODIPROD = :CODIPROD", TABLE);
List<OracleParameter> parameters = new List<OracleParameter>();
parameters.Add(new OracleParameter(":CODIPROD", id));
UPDATE
I'm using for retun:
OracleCommand command;
command.ExecuteReader();
UPDATE
I tried put Unicode=True on the ConnectionString but nothing
UPDATE
This is how I execute the query. Everything works fine with characters without accents:
OracleConnection connection = new OracleConnection();
connection.Open();
OracleTransaction transaction;
transaction = connection.BeginTransaction();
OracleCommand command;
command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = commandText;
OracleParameter parameter;
command.Parameters.Add(parameter);
reader = command.ExecuteReader();
while (reader.Read())
{
// Get data
}
So, the last try (yesterday 5 pm) I made this:
String x = "SELECT * FROM PROD WHERE TRANSLATE(LOWER(DESCSITE), 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc') LIKE LOWER(TRANSLATE('%"+str+"%', 'âáàãêéèîíìôóòõûúùç', 'aaaaeeeiiioooouuuc'))";
And works fine. But this way I know that is not right.
You are calling the functions in the wrong order. The TRANSLATE function is case-sensitive. Therefore you must make the strings lower case before translating.
SELECT * FROM {0}
WHERE TRANSLATE(LOWER(DESCSITE), {2}) LIKE TRANSLATE({1}, {2})
Also, the second LOWER is superfluous, since you do with str.ToLower() already.
UPDATE
It is still not clear how you really execute the query. Here is an example of how it can be done
string connectionString = "...";
string query = "...";
using (var connection = new OracleConnection(connectionString)) {
var command = new OracleCommand(query);
command.Parameters.Add(":DESCSITE", OracleType.NVarChar);
connection.Open();
using (OracleDataReader reader = command.ExecuteReader()) {
int descSiteOrdinal = reader.GetOrdinal("DESCSITE");
while (reader.Read()) {
Console.WriteLine(reader.GetString(descSiteOrdinal));
}
}
}
I've resolved it adding this in my connectionString like this (Unicode=true;):
protected string conexionOraclePruebas = #"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=xxx)(HOST=xxx)(PORT=xxx)))(CONNECT_DATA=(SERVER=xxx)(SERVICE_NAME=xxx)));"
+ " User Id=xxx;Password=xxx;Min Pool Size=x;Connection Lifetime=x; "
+ " Unicode=true;";
My query was:
query += " AND translate(UPPER(" + field + "), 'ÁÉÍÓÚÀÈÌÒÙÃÊÎÕÛÂÄËÏÖÔÜÇÑ', 'AEIOUAEIOUAEIOUAAEIOOUCN') "
+"LIKE translate(UPPER('%" + this.value.ToString() + "%'), 'ÁÉÍÓÚÀÈÌÒÙÃÊÎÕÛÂÄËÏÖÔÜÇÑ', 'AEIOUAEIOUAEIOUAAEIOOUCN')";

SQL SELECT With Stored Procedure and Parameters?

I've been writing a lot of web services with SQL inserts based on a stored procedure, and I haven't really worked with any SELECTS.
The one SELECT I have in mind is very simple.
SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization
WHERE AD_SID = #userSID
However, I can't figure out based on my current INSERT code how to make that into a SELECT and return the value of ReturnCount... Can you help? Here is my INSERT code:
string ConnString = "Data Source=Removed";
string SqlString = "spInsertProgress";
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("attachment_guid", smGuid.ToString());
cmd.Parameters.AddWithValue("attachment_percentcomplete", fileProgress);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
Here is where you are going wrong:
cmd.ExecuteNonQuery();
You are executing a query.
You need to ExecuteReader or ExecuteScalar instead. ExecuteReader is used for a result set (several rows/columns), ExecuteScalar when the query returns a single result (it returns object, so the result needs to be cast to the correct type).
var result = (int)cmd.ExecuteScalar();
The results variable will now hold a OledbDataReader or a value with the results of the SELECT. You can iterate over the results (for a reader), or the scalar value (for a scalar).
Since you are only after a single value, you can use cmd.ExecuteScalar();
A complete example is as follows:
string ConnString = "Data Source=Removed";
string userSid = "SomeSid";
string SqlString = "SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization WHERE AD_SID = #userSID;";
int returnCount = 0;
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#userSID", userSid);
conn.Open();
returnCount = Convert.ToInt32(cmd.ExecuteScalar());
}
}
If you wanted to return MULTIPLE rows, you can use the ExecuteReader() method. This returns an IDataReader via which you can enumerate the result set row by row.
You need to use ExecuteScalar instead of ExecuteNonQuery:
String query = "SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization WHERE AD_SID = #userSID ";
using (OleDbConnection conn = new OleDbConnection(ConnString)) {
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("userSID", userSID.ToString());
conn.Open();
int returnCount = (Int32) cmd.ExecuteScalar();
conn.Close();
}
}
cmd.executescalar will return a single value, such as your count.
You would use cmd.executereader when you are returning a list of records

Categories