I have a little problem with selecting max ID from my database. This is my code:
string checkcat = "SELECT MAX(PRODUCT_ID) FROM CMS_PRODUKTY WHERE (CATEGORY_ID = CATEGORY_ID) AND (CLIENT_ID = #CLIENT_ID)";
SqlCommand cmd2 = new SqlCommand(checkcat, con);
cmd2.Parameters.Add("#CATEGORY_ID", System.Data.SqlDbType.Int).Value = kategoria;
cmd2.Parameters.Add("#CLIENT_ID", System.Data.SqlDbType.Int).Value = HiddenField1.Value;
con.Open();
int noweid = Convert.ToInt32(cmd2.ExecuteScalar());
con.Close();
The point is the new int "noweid" should be 1 or higher - depend on product_id inside table, but it's returning 0. I don't have any idea why... The other variables - kategoria and HiddenField1.Value are correct.
Any ideas what did I do wrong?
You have
WHERE (CATEGORY_ID = CATEGORY_ID)
but you want
WHERE (CATEGORY_ID = #CATEGORY_ID)
You should also parse the string to int:
cmd2.Parameters.Add("#CLIENT_ID", System.Data.SqlDbType.Int).Value = int.Parse(HiddenField1.Value);
maybe kategoria is also a string, then parse it also to int.
Related
So I am trying to use two different inputs from a user to get two different values then multiply them together to get an answer.
//code to get value
SqlCommand cmd = new SqlCommand("select Charges, Students from Subs where Subject_name='" + Subject + "'and Level='" + Level + "'", con);
//code to read and times the values
var reader = cmd.ExecuteReader();
int Price = Convert.ToInt32(reader["Charges"]);
int NumS = Convert.ToInt32(reader["Subject_name"]);
int final = (Price*NumS) / 100;
status = final + "$";
You should try something like this:
// Define **parametrized** query
string query = "SELECT Charges, Students FROM dbo.Subs WHERE Subject_name = #SubjectName AND Level = #Level;";
using (SqlCommand cmd = new SqlCommand(query, con))
{
// define the parameters and set value
// I'm just *guessing* what datatype and what length these parameters are - please adapt as needed !
cmd.Parameters.Add("#SubjectName", SqlDbType.VarChar, 50).Value = Subject;
cmd.Parameters.Add("#Level", SqlDbType.Int).Value = Level;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int Price = reader.GetInt32(0); // index = 0 is "Charges" of type INT
// you are **NOT** selecting "Subject_Name" in your query - you therefore **CANNOT** read it from the SqlDataReader
// int NumS = Convert.ToInt32(reader["Subject_name"]);
int NumS = 1.0;
int final = (Price * NumS) / 100;
status = final + "$";
}
}
Points to ponder:
You should also put your SqlConnection con into a proper using (..) { ... } block to ensure disposal
You need to check the parameters - since you hadn't specified anything in your question, and also not posted any information about them, I can only guess
Be aware - the SqlDataReader might (and in a great many cases will) return multiple rows - which you need to iterate over
If you want to read out a column from the database table - it must be in the SELECT list of columns! You're trying to read out a column you're not selecting - that won't work, of course. ...
I've been googling something I dont really cant understand.
In short my problem is this;
When using this;
String sYear2 = "2020";
string query = #"Select decJan from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
The result is returning "111" (which is correct vaule of column decJan the year 2020.
But when trying this;
String sYear2 = "2020";
String sColumn2 = "decJan";
string query = #"Select " + #column + #" from tbFuGraddagar where intRecnum = (select intRecnum from tbfuGraddagar where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
cmd.Parameters.AddWithValue("#column", sColumn2);
I recieve "decJan" as result.
When googling all I have found that its not possible without dynamic SQL or that is bad design.
But I fail to understand what the diffrence is...all I want is to change the static code with a value similar to #year-parameter. the "interpretation" shouldn't care about the validation of SQL-syntax, it's just a matter och string-manipulation.
Or is it just me beeing a bad C#-coder?
Probably addwithvalue method is not valid for adding dynamic column names in select statements. I think you should use c# 8.0 feature, string interpolation to solve this problem. You can add column names with string interpolation. Can you try this approach :
String sYear2 = "2020";
string deccan = "decJan";
string query = $(Select {decJan} from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)
query = #query;
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
I have to add 4 values into my table:#SNTeacher,#name,#pwd and #courseID.The #courseID is a FK in my RegisterTeacher table and a PK I Courses table along with another attribute-#coursename.
My problem is that when I want to insert the values into the table, I get an error at #courseID saying that it can't convert from varchar to int although my #courseID is an int.
My #courseID and #coursename are binded to comboBoxcourse1 and it has DisplayMember-coursename and ValueMember=courseID.My opinion is that it makes the confusion between the two of them since #coursename is a varchar, but then again I don't see the logic since I'm adding the #courseID parameter to the table RegisterTeacher.
I also tried to parse it in 3 different ways that I have also found here, on Stack Overflow but still I get errors saying that the input string was not in a correct format.
This is my code with the error and in is also the last method I used to try to parse the value:
private void btnRegister_Click(object sender, EventArgs e)
{
string connString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\source\repos\VIAUniversityCollegeAttendanceApp\VIAUniversityCollegeAttendanceApp\DatabaseAttendanceStudents.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection con = new SqlConnection(connString);
con.Open();
SqlCommand cmd = new SqlCommand("Insert into RegisterTeacher values(#SNTeacher,#name,#pwd,#courseID) ", con);
cmd.Parameters.AddWithValue("#SNTeacher", textBoxSN.Text);
cmd.Parameters.AddWithValue("#name",textBoxName.Text);
cmd.Parameters.AddWithValue("#pwd", textBoxpwd.Text);
string nvarchar = "#courseID";
var one = int.Parse(nvarchar);
var bone = int.TryParse(nvarchar, out one);
cmd.Parameters.AddWithValue("#courseID", comboBoxcourse1.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Registration succesfull!");
}
This should work for you:
int parameterValue;
SqlParameter parameter = new SqlParameter("#courseID", SqlDbType.Int);
if(Int32.TryParse(comboBoxcourse1.SelectedValue?.ToString() ?? String.Empty, out parameterValue))
{
parameter.Value = parameterValue;
}
else
{
parameter.Value = DBNull.Value;
}
cmd.Parameters.Add(parameter);
New to stackoverflow and very much a c# beginner
Currently creating a form which produces a bar chart from data stored in a database. The chosen record is identified by pID (patient's ID) and tdate (Test date). These values are determined by 2 combo boxes that the user can select from, The problem I am having is that only the first and last records stored in the database are populating the barchart.
if (radioButtonTestResult.Checked)
{
foreach (var series in TestResultBarChart.Series)
{
series.Points.Clear();
}
string tdate = comboBox2.Text;
using (SqlConnection connection = new SqlConnection(#"Data Source= (LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MMSEDB.mdf;Integrated Security=True"))
{
connection.Open();
string sql = "SELECT T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,T_REGISTRATION_SCORE,T_ORIENTATION _SCORE,T_TIME FROM TEST_RESULTS WHERE P_ID='" + pID + "' AND T_DATE='"+ tdate +"'";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
MessageBox.Show("hello4");
String clockScoreString = reader["T_CLOCK_SCORE"].ToString();
MessageBox.Show(clockScoreString);
clockScore = Int32.Parse(clockScoreString);
String langScoreString = reader["T_LANGUAGE_SCORE"].ToString();
langScore = Int32.Parse(langScoreString);
String recallScoreString = reader["T_RECALL_SCORE"].ToString();
recallScore = Int32.Parse(recallScoreString);
String regScoreString = reader["T_REGISTRATION_SCORE"].ToString();
regScore = Int32.Parse(regScoreString);
String orientScoreString = reader["T_ORIENTATION_SCORE"].ToString();
orientScore = Int32.Parse(orientScoreString);
String timeScoreString = reader["T_TIME"].ToString();
timeScore = Int32.Parse(timeScoreString);
}
reader.Close();
}
}
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
}
Here is a pic of the data:
Test_results_table
here is a pic of the interface with the first record working:
interface
I know this has something to do with the reader but can't work out how to get to function correctly
Any help is very much appreciated
You are reading in a loop all the returned values, then exit from the loop and use just the last value to set your Points. You should move the Point settings inside the loop
....
while (reader.Read())
{
clockScore = Convert.ToInt32(reader["T_CLOCK_SCORE"]);
langScore = Convert.ToInt32(reader["T_LANGUAGE_SCORE"]);
recallScore = Convert.ToInt32(reader["T_RECALL_SCORE"]);
regScore = Convert.ToInt32(reader["T_REGISTRATION_SCORE"]);
orientScore = Convert.ToInt32(reader["T_ORIENTATION_SCORE"]);
timeScore = Convert.ToInt32(reader["T_TIME"]);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
reader.Close();
Note that your query is built using string concatenation. This is a well known problem with database code. Never do it and use a parameterized query
EDIT
Looking at your comment below, I repeat the advice to use a parameterized query instead of string concatenation. Not only this avoid Sql Injection hacks but also you don't leave the job to understand the meaning of your values to the database engine
DateTime tDate = Convert.ToDateTime(comboBox2.Text);
......
string sql = #"SELECT
T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,
T_REGISTRATION_SCORE,T_ORIENTATION_SCORE,T_TIME
FROM TEST_RESULTS
WHERE P_ID=#id AND T_DATE=#date";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#id", SqlDbType.Int).Value = pID;
command.Parameters.Add("#date", SqlDbType.Date).Value = tdate;
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
....
In this example I assume that the variable pID is of type integer and the variable tDate is of type DateTime matching the type of the database fields. This doesn't leave any doubt to the database engine on your values.
Of course if the fields are of different type then you should change the SqlDbType accordingly.
I know that this question has been asked many times, And I have read many many answers, yet I can't figure out what is wrong. It's been hours. Any help would be soo appreciated. I am just trying to call a stored procedure in an ASP page, and I am unable to add the parameter properly, getting the exception that it is not in the collection.
I have modified my proc as follows to try to make it simple and isolate the issue.
ALTER PROCEDURE [dbo].[up_validateUserWithClinicCount]
#HTID INT = 0,
#ValidUserID INT OUTPUT,
#MultiClinicFlag INT OUTPUT
AS
DECLARE #vClinicCount INT = null
DECLARE #vUserValid INT = null
BEGIN
SET #ValidUserID = 2
SET #MultiClinicFlag = 1
END;
AND the C# code
String connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["PC3PaymentConnection"].ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand("up_validateUserWithClinicCount", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#HTID", htId);
SqlParameter uidOut = new SqlParameter("#ValidUserID", SqlDbType.Int);
uidOut.Size = 4;
uidOut.Direction = ParameterDirection.Output;
cmd.Parameters.Add(uidOut);
SqlParameter pMultiClinics = new SqlParameter();
pMultiClinics.ParameterName = "#MultiClinicFlag";
pMultiClinics.SqlDbType = SqlDbType.Int;
pMultiClinics.Direction = ParameterDirection.Output;
cmd.Parameters.Add(pMultiClinics);
try
{
cmd.ExecuteNonQuery();
//--> Error points to the next line, and I have tried to use int.parse rather than convert also, with the same error -- parameter not in collection
MultiClinics = Convert.ToInt16(cmd.Parameters["pMultiClinics"].Value);
PC3User = Convert.ToInt16(uidOut.Value.ToString());
}
catch (SqlException sqlEx)
{
LbMsg.ForeColor = System.Drawing.Color.Red;
LbMsg.Text = sqlEx.Message;
}
}
}
Thanks if you can see what I am missing.
You have an object reference for the parameter already, you don't need to grab it from the parameters collection. Also, sql ints are 32-bit.
MultiClinics = (int)pMultiClinics.Value;
To retrieve from the parameter collection, use the ParameterName you gave it:
MultiClinics = (int)cmd.Parameters["#MultiClinicFlag"].Value;