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())
{
}
}
}
Related
I tried to return a row by executing following SQL query in C#:
SqlCommand cmd = new SqlCommand();
string selectquery = "SELECT TOP (1) [ZVNr] ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
cmd.CommandText = selectquery;
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
try
{
sqlConnection.Open();
int recordsAffected = cmd.ExecuteNonQuery();
if(recordsAffected != -1)
{
return 0;
}
else
{
return 1;
}
And the "ZVNR_TABLE" looks like this:
ZVNR | varchar (50)
20170530-01
The result is always --> recordsAffected = -1
Although when I'm executing the same SQL query in Microsoft SQL Server Management Studio, it works.
You're using a SELECT statement in your code with cmd.ExecuteNonQuery which is used for INSERT or UPDATE statements.
You have to use a SQLDataReader (more than 1 row and(!) column) or Scalar (1 row/1col = one "item").
MSDN Example for SQLDataReader:
//SELECT col1, col2, ..., coln FROM tbl;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
MSDN Example for ExecuteScalar:
//SELECT COUNT(*) FROM region; or any other single value SELECT statement
int count = (int)cmd.ExecuteScalar(); //cast the type as needed
If you want the affected count after you change items in your database, you can get it by using cmd.ExecuteNonQuery which returns that count:
MSDN Example for ExecuteNonQuery:
//INSERT INTO tbl (...) VALUES (...) or any other non-query statement
int rowsAffected = (Int32)cmd.ExecuteNonQuery();
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
Because you are Selecting the data from the datatable not inserting or updating the records that's why recordsAffected is always -1
Answers given above are ok but if you want just to see if it exist you can do a count instead
using (SqlConnection connection = new SqlConnection(connectionstring))
{
string query = "SELECT Count([ZVNr]) ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
try
{
connection.Open();
int result = (int)cmd.ExecuteScalar();
}
}
}
ExecuteNonQuery() is used for INSERT or UPDATE statements and returns the number of rows affected.
If you want to return a single field of a row, you have to use ExecuteScalar()
using (SqlConnection connection = new SqlConnection(connectionstring))
{
string query = "SELECT TOP (1) [ZVNr] ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
connection.Open();
object result = cmd.ExecuteScalar();
}
}
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(*)
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());
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
I have two columns syntax and query in my table Table1. Syntax contains data called po and a query called select * from po_pomas_pur_order_hdr where pomas_pono =. I got this query value by using
SqlDataAdapter da = new SqlDataAdapter("select query from Table1 where syntax = '" + textBox1.Text + "'", conn);
And my problem is that I need to dynamically pass another value inside the query which I retrived using dataadapter like this:
SqlDataAdapter da1 = new SqlDataAdapter(da.tostring() +"'"+ textBox1.Text +"'", conn)
The resulting query should be like this:
select * from po_pomas_pur_order_hdr where pomas_pono = '2PO/000002/09-10'
But it is not possible. How to get a query like this? Any suggestion?
SqlDataAdapter is used to fill datasets and datatables. You cannot obtain the result of a query with ToString(). I think you want to use SqlCommand to execute your first query to retrieve the actual query to run from the database like this:
string query = null;
using (var command = new SqlCommand("select query from Table1 where syntax = #Syntax", conn))
{
command.Parameters.AddWithValue("#Syntax", textBox1.Text);
query = command.ExecuteScalar(); // this assumes only one query result is returned
}
Then you can use the data adapter to fill it:
SqlDataAdapter da1 = new SqlDataAdapter(query +"'"+ textBox1.Text +"'", conn);
Although I would suggest to use parameters for that as well.
in this way is more safe: dotnetperls
He check the "'" and the "\", check the type of the fields etc...
Code from the example above (is the same for insert delete and update):
using (SqlCommand command = new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE #Name", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("Name", dogName));
//
// Read in the SELECT results.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
int weight = reader.GetInt32(0);
string name = reader.GetString(1);
string breed = reader.GetString(2);
Console.WriteLine("Weight = {0}, Name = {1}, Breed = {2}", weight, name, breed);
}
}
I suggest you to use SqlParameters. Here is example how to use DataAdapter and parameters.
Provided that you have a DataSet you intend to fill using the adapter and that you adjust the queries to use parameters in order to avoid sql injection you should be able to use something like this:
string query;
using(var sqlCommand = new SqlCommand(
"select query from Table1 where syntax=#syntax", conn))
{
sqlCommand.Parameters.AddWithValue("syntax", textBox1.Text);
query = (string)sqlCommand.ExecuteScalar();
}
using(var dataAdapter = new SqlDataAdapter())
using(var dataCommand = new SqlCommand(query, conn))
{
dataCommand.Parameters.AddWithValue("parameter", poNumber);
dataAdapter.SelectCommand = dataCommand;
dataAdapter.Fill(myDataSet);
}