Problem on querystring in SQL cmd - c#

I have the next code:
private int bla(out int itemsMin, out int purchase)
{
string ID = (Request.QueryString["Ttrsid"] ?? "0").ToString();
{
SqlConnection connection = new SqlConnection("Data Source=*****;Initial Catalog=****;User ID=****;Password=*****;Integrated Security=False;");
string commandtext = "SELECT Min FROM myItems WHERE itemId=#ID";
SqlCommand command = new SqlCommand(commandtext, connection);
connection.Open();
command.Parameters.AddWithValue("#ID", ID); //Adds the ID we got before to the SQL command
itemsMin = (int)command.ExecuteScalar();
string commandtext2 = "SELECT COUNT (*) FROM purchase";
SqlCommand command2 = new SqlCommand(commandtext2, connection);
purchase = (int)command2.ExecuteScalar();
}
return 0;
}
The code is for two labels that i use - one to get the minimum number (itemsMin), and the other is for the count of the purchase.
I'm using the querystring to get the values by the itemid that the user watching on him now.. (from the address bar (for example: items.aspx?Ttrsid=5 so i want to see the minimum number of the Ttrsid = 5).
Everything works fine. when i'm on the Ttrsid = 1 , Ttrsid = 2 - i get what i want, but when i'm enterd to the Ttrsid = 3 and so on - that's give me the error:
System.NullReferenceException
To the line:
itemsMin = (int)command.ExecuteScalar();
.. and it's not null.. the item have all the required fields like Ttrsid = 2 .... so what wrong here?
The next code is the use of the command above:
int i, p; // variable need not be initialized
Console.WriteLine(bla(out i, out p));
if (i < p)
{
haha.Visible = true;
}
else
{
haha2.Visible = true;
}
Console.WriteLine(i);
Console.WriteLine(p);
i = itemsMin , p = purchase .

I'm guessing there is no matching row in the db, so no rows returned. Sanity-check the result from ExecuteScalar - in particular, check it for null before casting to int. It is also possible that the column contains a null, but maybe I'd expect DBNull.Value for that.
Also - use using on all the IDisposable objects here; the connection and command in particular.

I assume below pasted variable is a int type variable
purchase = (int)
Hence you may not be able to convert null values to an integer so try it changing the sql command as below
SELECT isNull(COUNT (*),0) FROM purchase
#Marc I'm really sorry about it
Don't you want to specify a column name next to the min statement? As below
SELECT Min(columnName) FROM myItems WHERE itemId=#ID ?

Related

Why does my count command in mysql return wrong value -1?

I'm using gcloud mysql and inserting values and stuff using c#.
Im trying to get amount of records in table Categories_tbl. My code is:
but after executing x is equal to -1 which wrong. what could it be?
MySqlCommand count_categories = new MySqlCommand(
"SELECT COUNT(CategoryId) FROM Categories_tbl;",
connection);
x = count_categories.ExecuteNonQuery();
Well,
count_categories.ExecuteNonQuery();
returns how many records are affected; you don't call insert, update, delete so you have -1. Put instead
x = count_categories.ExecuteScalar();
which execute the query and return single result. Another (more wordy) possibility
using (var reader = count_categories.ExecuteReader()) {
if (reader.Read())
x = Convert.ToInt32(reader[0]); // if you want int as a result
else {
// cursor is empty
}
}
Edit: which can be used if you want to read several records, e.g.
List<Category> list = new List<Category>();
using (var reader = count_categories.ExecuteReader()) {
while (reader.Read()) {
//TODO: put the right syntax here
Category category = new Category() {
Name = Convert.ToString(reader["Name"]),
};
list.Add(category);
}
}
This is not a "NonQuery", this is a query and you want the result:
x = count_categories.ExecuteScalar();
Since I don't know what type your x is, you may need to cast it to the proper type.

IF condition check inside USING method and SqlConnection

I am trying to run data validation, execute some code and pass data from one SQL query to another.
My current code looks like the below:
public string SelectUniqueKeyNumber()
{
string newList = string.Join(Environment.NewLine, listOfSkus).ToString();
string key_id;
string sqlConnectionString = #"someConnectionString";
using (SqlConnection connection = new SqlConnection(sqlConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("select top 1 KEY_NUMBER from MyTable where QTY_ON_HAND > 0 " + newList + " order by NEWID()", connection);
SqlDataReader readerKey = command.ExecuteReader();
readerKey.Read();
key_id = String.Format(readerKey[0].ToString());
}
SelectSkuNumber(key_id);
return key_id;
}
What I am trying to do is to check if my readerKey.Read() is not returning null value. If it does then stop the process, otherwise continue. I've tried it in the way as shown below:
public string SelectUniqueKeyNumber()
{
string newList = string.Join(Environment.NewLine, listOfSkus).ToString();
string key_id;
string sqlConnectionString = #"someConnectionString";
using (SqlConnection connection = new SqlConnection(sqlConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("select top 1 KEY_NUMBER from MyTable where QTY_ON_HAND > 0 " + newList + " order by NEWID()", connection);
SqlDataReader readerKey = command.ExecuteReader();
readerKey.Read();
if(readerkey.Read().ToString() == null)
{
//--- stop processing
}
else
{
key_id = String.Format(readerKey[0].ToString());
}
}
SelectSkuNumber(key_id); //---> Then ...(key_id) is not declared value
return key_id;
}
By doing so, I cannot access and pass data of SelectSkuNumber(key_id) due to: Use of unassigned local variable 'key_id'
Any ideas?
All you need do is assign something to key_id when you declare it, like:
string key_id = null; // not string key_id;
and later, after the using:
if (key_id != null)
{
SelectSkuNumber(key_id); //---> Then ...(key_id) is not declared value
}
return key_id;
The caller of the function should, of course, know what to do if a null is returned.
To avoid that particular problem, you can assign some value or nnull to key_id, eg. key_id = "";.
But you have some more problem there:
You are prone to SQL injection, you should use Parameters collection of SqlCommand class.
Are you sure you are concatenating your query correctly? Let's suppose
newList = {"some", "thing"};
Then your query would be:
select top 1 KEY_NUMBER
from MyTable where QTY_ON_HAND > 0
some
thing
order by NEWID()
Which is very, very incorrect to say the least.
if(readerkey.Read().ToString() == null) condition... Read returns bool, which is either true or false, it isn't reference type, so ToString() will never be null, thus the condition will always fail. If you want to check if there was NULL in database you should check:
if (readerKey.Read() && readerKey["KEY_NUMBER"] == DBNull.Value)
which first read row, then receives value of column in that row. It uses short-circuiting for the case, where no records are returned.
readerKey.Read(); is unnecessary before the if statement.

Check if a database table contains any rows

I'm loading data into a form with 3 Entry controls.
The object I am using for this is called mySettings, which is an object of SystemSettings, a class and database table in my SQLite database.
So far I have this code, and it works as is.
var db = new SQLiteConnection(dbPath);
Entry txtServer;
txtServer = new Entry { FontSize = 10 };
controlGrid.Children.Add(txtServer, 2, 0);
Grid.SetColumnSpan(txtServer, 4);
SystemSettings mySettings;
mySettings = db.Get<SystemSettings>(0);
txtServer.Text = mySettings.FTPServer;
However, I need to check whether SystemSettings contains any rows in the table before I load values in.
I've seen a few guides online.
Some say use something along the lines of
SQLiteCommand cmd;
cmd = new SQLiteCommand(db);
...
int result = Convert.ToInt32(db.ExecuteScalar)
However, I get an error there saying
SQLiteCommand does not contain any method containing x parameters
no matter how many I pass in (0 or more).
There also doesn't appear to be a method as part of db.
So how can I check whether SystemSettings contains any rows, before trying to use data that doesn't exist?
The pattern below should work. The .ExecuteScalar() method is actually on the command and not the connection.
int count;
using (SQLiteConnection db = new SQLiteConnection("MY_CXN_STRING"))
using (SQLiteCommand cmd = new SQLiteCommand("SELECT COUNT(*) FROM SystemSettings"))
{
db.Open();
count = (int)cmd.ExecuteScalar();
db.Close();
}
bool hasRows = count != 0;
Basically you want to clear
SystemSettings
Try just running a query that returns nothing against the database. For instance:
SystemSettings = $"SELECT * FROM TABLE_NAME WHERE COLUMN_NAME IS 'INVALID_EXPRESSIONdjeiq48724rufnjdrandom stuff'";
Not the most elegant solution by any means, but it works.
What you want to do is to get the first row in you SystemSettings table if any:
You should therefore execute the following Sql Statement (or something similar) and check if a result is returned:
Select * from SystemSettings LIMIT 1;
You can execute the query and check the result like this:
public bool DoesTableContainRows(string tableName, SQLiteConnection connection)
{
var command = new SQLiteCommand($"Select * from {tableName } LIMIT 1;", connection);
var resultReader = command.ExecuteReader();
// check whether or not a row was returned
bool containRows = resultReader.Read();
resultReader.Close();
return containRows;
}
Edit:
Shows how to check if a table contains rows using .NET and Microsoft.Data.Sqlite including better disposing of resources.
public bool DoesTableContainRows(string tableName, SqliteConnection connection)
{
using (var command = new SqliteCommand($"Select * from {tableName } LIMIT 1;", connection))
{
using (var resultReader = command.ExecuteReader())
{
// check whether or not a row was returned
bool containRows = resultReader.Read();
resultReader.Close();
return containRows;
}
}
}

Can't read float value from SQL Server database

I use SQL Server to build my database and SqlDataReader to read data from it.
command.Connection = cn;
command.CommandText = "SELECT * FROM test";
SqlDataReader rd = command.ExecuteReader();
while(rd.Read())
{
double d = (double) rd.GetValue(0);
}
The column (0) I am trying to get value from is a 'float' type and has value '3.5' . As mapping data type from this MSDN link, the type of the object returned by rd.GetValue(0) must be 'double'. But the code above returns to variable 'd' value '0.0'. I tried this line:
double d = Convert.ToDouble(rd.GetValue(0));
But it still returns '0.0' to variable 'd'.
I tried searching on Google and StackOverflow but there is no result.
What am I missing? Help me!
As it is now, your code iterates over all the records (if there are many) an takes the last entry, which since you have no order by clause, may differ in every query execution. If indeed you want to only take 1 value, use ExecuteScalar together with an order by clause:
command.Connection = cn;
command.CommandText = "SELECT TOP 1 * FROM test order by myfield desc"; //or asc
double result = (double)command.ExecuteScalar();
Otherwise have all the result saved in a list:
...
List<double> result = new List<doulbe>();
while(rd.Read())
{
result.Add(double.Parse(rd[0].ToString());
}
Finally, if you need only the 1st field, for performance reasons, is far better not to use * but explicit set the field you want:
"SELECT TOP 1 myfield FROM test order by myfield desc"; //or asc
you can try it;
double d = (double) rd.GetValue(0);
to
double d = 0;
double.TryParse(rd["ColumnName"].ToString().Replace('.',','),out d);
OR:
double d = double.Parse(rd["ColumnName"].ToString(), CultureInfo.InvariantCulture);
This here works fine for me, im getting 3,5 in my list
List<double> columnData = new List<double>();
using (SqlConnection connection = new SqlConnection("Server=EGC25199;Initial Catalog=LegOgSpass;Integrated Security=SSPI;Application Name=SQLNCLI11.1"))
{
connection.Open();
string query = "SELECT * FROM [dbo].[floattable]";
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
columnData.Add(reader.GetDouble(0));
}
}
}
}
Oh I have found the answer. Nothing wrong with the code I wrote. The problem is that I place the breakpoint on the 'double d = (double) rd.GetValue(0)' line. That is, 'd' value is not assigned yet so that on the debug screen it returns '0.0'.
Sorry for this mistake and thank you all Stack-Over-flowers for spending your time helping me!!!!

How to get a new id when there is no records in database?

when I run this method GetNewID() it should return max Product_Id + 1 from database. So if the Max Product_Id in the database is 20 the next one should be 21.
That's working fine.
But what's not working is when there is no records in database and it's null. I've tried with a different select statement and some if-statements but didn't work. Do you have any ideas on how I can solve this problem? Thanks in advance.
public static int GetNewId()
{
string selectString = #"SELECT MAX(Product_Id) FROM Products";
try
{
newId= 0;
connection = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=DB;Integrated Security=SSPI;");
connection.Open();
SqlCommand cmdSelectLastId = new SqlCommand(selectString, connection);
newId = Convert.ToInt32(cmdSelectLastId.ExecuteScalar());
}
finally
{
if (connection != null)
{
connection.Close();
}
}
return newId + 1;
}
Make the query return zero instead of null when there are no records:
string selectString = #"SELECT ISNULL(MAX(Product_Id),0) FROM Products";
The simple answer is:
SELECT ISNULL(MAX(Product_Id), 0) FROM Products
However, the way in which you're implementing this is potentially fraught with danger. For example, have you considered two concurrent processes running through this code one immediately after the other, but before the record for the first has been inserted into the database?
Depending upon your database, you may be better off using an automatically generated ID, or a GUID.
SELECT COALESCE(MAX(Product_Id), 0) FROM Products
And you can add 1 within the query, too:
SELECT COALESCE(MAX(Product_Id), 0) +1 FROM Products

Categories

Resources