sqlite database not returning results - c#

Why my query does not return results?
I'm using C#.
It returns column headers but no rows. Is there a problem with my select statement?
here's my code :
conn = new SQLiteConnection("Data Source=local.db;Version=3;New=False;Compress=True;");
DataTable data = new DataTable();
SQLiteDataReader reader;
using (SQLiteTransaction trans = conn.BeginTransaction())
{
using (SQLiteCommand mycommand = new SQLiteCommand(conn))
{
mycommand.CommandText = "SELECT * FROM TAGTABLE WHERE TAG = '"+tag+"' ;";
reader = mycommand.ExecuteReader();
}
trans.Commit();
data.Load(reader);
reader.Close();
reader.Dispose();
trans.Dispose();
}
return data;
The TAGTABLE has following fields:
TID int,
Tag varchar(500),
FilePath varchar(1000)

You don't need the transaction, try the following:
DataTable data = new DataTable();
using (SQLiteConnection conn = new SQLiteConnection("Data Source=local.db;Version=3;New=False;Compress=True;"))
using (SQLiteCommand mycommand = new SQLiteCommand(conn))
{
mycommand.CommandText = "SELECT * FROM TAGTABLE WHERE TAG = #tag;";
mycommand.Parameters.AddWithValue("#tag", tag);
conn.Open();
using (SQLiteDataReader reader = mycommand.ExecuteReader())
{
data.Load(reader);
}
}
return data;
The most likely reason this won't return anything is if the SELECT doesn't yield any results.
Also note that anything implementing the IDisposable interface can be used in conjunction with the using statement, so manual closing / disposal of objects afterwards is not required.
Notice that the SQL has changed to use a parameterized query, this will help reduce the likelihood of SQL injection attacks, and is generally cleaner.

Since you don't show sample data and what should be returend some general pointers only:
The way you build the SQL is wide open to SQL incjection (a serious security issue)
Depending on the value of tag (for example if it contains ') the above SQL Statement would do something you don't expect
Since everything is wrappend in using (a good thing!) the question is, whether there is some exception thrown inside the using block (check with the debugger)
why are you using a transaction ? I can't see any reason which makes that necessary...
Please show some sample data with param value and expected result...

Related

How do I solve error in ExecuteReader();?

I am facing an issue with ExecuteReader(). When I am writing MySqlDataReader reader = cmd.ExecuteReader();, I have a red line under cmd.ExecuteReader(). I am using Windows Form Application to read database from Microsoft SQL Server and using C# and OOP.
SqlConnection con = new SqlConnection(constring);
con.Open();
if (con.State == System.Data.ConnectionState.Open)
{
string q = "SELECT * from BuildingA30 where CONVERT(VARCHAR, FlatNo) = N'" + a11 + "' ";
Console.WriteLine("Read all");
Console.WriteLine(q);
SqlCommand cmd = new SqlCommand(q, con);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
textBox1.Text = reader.GetString("tenantname");
textBox2.Text = reader.GetString("FlatNo");
}
textBox1.Text = q.ToString();
MessageBox.Show("Connection success");
}
Problem is that SqlCommand.ExecuteReader returns a SqlDataReader, not a MySqlDataReader.
Here:
SqlCommand cmd = new SqlCommand(q, con);
MySqlDataReader reader = cmd.ExecuteReader();
You're mixing ADO.NET providers. Either use the SQL Server provider classes (if the database is SQL Server), or the MySql ones if it's MySql. Not both.
You install Dapper, then you don't have to waste your life writing boring, menial data reader code..
With Dapper that entire code you've written (yep all of it) would become something like `
using(var con = new MySqlConnection(...)){
var rental = con.Query<RentalInfo>(
"SELECT * FROM BuildingA30 WHERE flatNo = #f",
new { f = all }
};
//use your rental object
This code is massively improved over the one you have there because:
it's simple, quick to write, easy to read and debug
it uses parameters and doesn't suffer from sql injection hacking risks - yours does
it is strongly typed and can be async (note, mysql hasn't implemented async for their db provider, apparently but using async is a good habit to get into) - you just need to create a class called RentalInfo and add the relevant names properties to it;
it doesn't call functions on the left hand side of an operator in the WHERE clause. Always a bad idea; don't call functions on millions of rows, call functions on constants and leave table data alone
http://dapper-tutorial.net
Note: I have no affiliation to Dapper or the guys who maintain that tutorial site

How to call following oracle function in ADO.NET using asp.net c#

How to call following oracle function in ADO.NET using asp.net c#
CREATE FUNCTION AuthenticateUser(UserName IN VARCHAR2,Password IN VARCHAR2)
RETURN NUMBER
IS
Counts NUMBER;
rval Number;
BEGIN
SELECT COUNT(USERNAMES)
INTO Counts
FROM tblUsers WHERE USERNAMES = UserName AND PASSWORDS = Password;
IF Counts = 1 THEN
rval:=1;
ELSE
rval:=-1;
END IF;
RETURN(rval);
END;
First you would need the Oracle ADO.NET library (something like Oracle.DataAccess.dll?), and I'm not sure where you'd obtain that but Oracle should be able to help with it. Once you have that, you would use the objects it provides to perform queries. For example, if you want to fill a DataSet from a query it might look like this:
using (var connection = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleDB"].ConnectionString))
using (var command = new OracleCommand(query, connection))
using (var dataAdapter = new OracleDataAdapter(command))
using (var dataSet = new DataSet())
{
connection.Open();
dataAdapter.Fill(dataSet);
connection.Close();
return dataSet;
}
Notice the objects like OracleConnection and OracleCommand which come from that library. As long as you have a valid Oracle connection string, those objects should work just fine:
<add name="OracleDB" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=some.host.name)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=DEV)));User Id=username;Password=password;"
providerName="Oracle" />
I think this should work. This presupposes you have set up your connection properly into the "conn" object.
OracleCommand cmd = new OracleCommand(#"select AuthenticateUser(:USER, :PASS) " +
"from dual", conn);
cmd.Parameters.Add(new OracleParameter("USER", OracleDbType.VarChar));
cmd.Parameters.Add(new OracleParameter("PASS", OracleDbType.VarChar));
cmd.Parameters[0].Value = "yoda";
cmd.Parameters[1].Value = "jed1!";
int result = (int)cmd.ExecuteNonQuery();
Also, I know inline SQL is discouraged, but I was hopeful that this would demonstrate the concept.

Explain me this SELECT dbo.TableName(#variable) statement

I'm working on one program that I need to modify a little. There's one SQL statement I don't understand what it does (or basically how it does it).
string query = "SELECT dbo.BusinessMinutes(#start,#end,#priorityid)";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#start", SqlDbType.DateTime).Value = start;
cmd.Parameters.Add("#end", SqlDbType.DateTime).Value = end;
cmd.Parameters.Add("#priorityid", SqlDbType.UniqueIdentifier).Value = priorityId;
SqlDataAdapter READER = new SqlDataAdapter();
READER.SelectCommand = cmd;
DataTable table = new DataTable();
READER.Fill(table);
if (table.Rows.Count == 1)
{
minutes = (int)table.Rows[0][0];
}
So can someone explain me the SELECT statement there. The end result (minutes) is as expected so it works but that syntax confuses me. Is this somehow equal to SELECT * FROM dbo.BusinessMinutes WHERE...
Is this commonly used and does this syntax has some special name so I could name my question better? Thank you in advance.
dbo.BusinessMinutes has to be a UDF (User Defined Function) that returns a simple scalar value based on a starting date, an ending date and a priority indicator.
Scalar functions, be it UDF or native, can be used in a SELECT statement to produce a field in the returned resultset. Thus, the code you have is perfectly legal.
For more information about scalar UDF, read this MSDN article.
As a side note, a better implementation for that code would be this:
string query = "SELECT dbo.BusinessMinutes(#start,#end,#priorityid)";
using (SqlCommand cmd = new SqlCommand(query, con))
{
cmd.Parameters.Add("#start", SqlDbType.DateTime).Value = start;
cmd.Parameters.Add("#end", SqlDbType.DateTime).Value = end;
cmd.Parameters.Add("#priorityid", SqlDbType.UniqueIdentifier).Value = priorityId;
// assuming connection is already open
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read()) minutes = reader.GetInt32(0);
}
}
If all you want is to init the minutes variable, using SqlDataReader will be more efficient and performant than creating a SqlDataAdapter and a DataTable. The using statements will also make sure your SqlCommand and SqlDataReader objects gets disposed of properly.
It is not a table name. I think you call into a FUNCTION.
how to create and call scalar function in sql server 2008
has more explanations and examples.

Understanding of nested SQL in C#

using (var connection = new SqlConnection(...))
{
string sql = "SELECT * FROM tableA";
using (var command = new SqlCommand(sql,connection))
{
using (var reader = command.ExecuteReader(...))
{
//***************Sample Start
string sql2 = "INSERT into tableB(column1) VALUES('"+reader["column1"]+"')";
using (var command2 = new SqlCommand(sql2,connection))
{
...
}
//***************Sample End
}
}
}
By using the above code snippet, I believe its the best practice to deal with SQL in C#. Now after I retrieve a list of records from tableA, for each of the row I would like to insert into tableB.
However, it's throwing an exception
There is already an open DataReader associated with this Command which must be closed first
I know this problem can be solved by creating another method and insert into the table from there, I'm wondering if there is any other way. Thanks for any input.
You need to use a different sql connection for the insert than for the select...
...but we can do even better. You can re-write this to be one sql statement, like so:
INSERT into tableB(column1)
SELECT column1 FROM tableA
And then run it all at once like this:
string sql = "INSERT into tableB(column1, column2) SELECT column1, #othervalue As column2 FROM tableA;";
using (var connection = new SqlConnection(...))
using (var command = new SqlCommand(sql,connection))
{
command.Paramters.Add("#othervalue", SqlDbType.NVarChar, 50).Value = "something";
connection.Open();
command.ExecuteNonQuery();
}
The single sql statement is typically much faster, and you end up with less code, too. I understand that this is likely a simplified example of your real query, but I promise you: you can re-write it all as one statement.
Additionally, sometimes you still want to do some client-side processing or display with the new records after the insert or update. In that case, you still only need to send one call to the database, but there will be two separate sql statements in that single call. The final code would look more like this:
string sql = "INSERT into tableB(column1, column2) SELECT column1, #othervalue As column2 FROM tableA;"
sql += "SELECT columnn1, #othervalue As column2 FROM tableA;";
using (var connection = new SqlConnection(...))
using (var command = new SqlCommand(sql,connection))
{
command.Paramters.Add("#othervalue", SqlDbType.NVarChar, 50).Value = "something";
connection.Open();
using (var reader = command.ExecuteReader() )
{
while (reader.Read() )
{
//...
}
}
}
And because someone else brought up MARS (multiple active result sets), I'll add that while this can work, I've had mixed results using it for inserts/updates. It seems to work best when everything that shares a connection is only doing reads.
As has been mentioned in comments, you need a separate database connection for the insert. Each connection can handle one active statement at a time, and you have two here - one for the SELECT, one (at a time) for the INSERT.
Try this for instance:
string srcqry = "SELECT * FROM tableA";
using (SqlConnection srccon = new SqlConnection(ConnectionString))
using (SqlCommand srccmd = new SqlCommand(srcqry, srccon))
{
srccon.Open();
using (SqlDataReader src = srccmd.ExecuteReader())
{
string insqry = "INSERT INTO tableB(column1) VALUES(#v1)";
// create new connection and command for insert:
using (SqlConnection inscon = new SqlConnection(ConnectionString))
using (SqlCommand inscmd = new SqlCommand(insqry, inscon))
{
inscmd.Parameters.Add("#v1", System.Data.SqlDbType.NVarChar, 80);
inscon.Open();
while (src.Read())
{
inscmd.Parameters["#v1"].Value = src["column1"];
inscmd.ExecuteNonQuery();
}
}
}
}
Using parameters solves the SQL Injection vulnerability. You should always do this rather than building the query string from raw user input, or from data that you're pulling from a database, or... well, always. Write some helper methods to make it easier if you like, just make sure you do it.
aside from a bad example, why not just simplify the query to
insert into TableB (column1) select column1 from TableA

How do I retrieve the result of an ADO.NET SqlCommand?

Ok either I'm really tired or really thick at the moment, but I can't seem to find the answer for this
I'm using ASP.NET and I want to find the amount of rows in my table.
I know this is the SQL code: select count(*) from topics, but how the HECK do I get that to display as a number?
All I want to do is run that code and if it = 0 display one thing but if it's more than 0 display something else. Help please?
This is what I have so far
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
SqlConnection con = new SqlConnection(connectionString);
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
if (topiccmd == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
but I know I'm missing something seriously wrong. I've been searching for ages but can't find anything.
PHP is so much easier. :)
Note that you must open the connection and execute the command before you can access the result of the SQL query. ExecuteScalar returns a single result value (different methods must be used if your query will return an multiple columns and / or multiple rows).
Notice the use of the using construct, which will safely close and dispose of the connection.
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
con.Open();
int numrows = (int)topiccmd.ExecuteScalar();
if (numrows == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
}
ExecuteScalar is what you're looking for. (method of SqlCommand)
Btw, stick with C#, there's no way PHP is easier. It's just familiar.
You need to open the connection
This might work :
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "select count(*) from topics";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
sqlConnection1.Close();
Similar Question: C# 'select count' sql command incorrectly returns zero rows from sql server

Categories

Resources