Retrieving data from a reader and saving it in a double variable - sql

I'm making a project to issue tickets to a company.For this,I use a table to store the price of a ticket of adults and children.
In my program,I use a reader to retrieve these values in the table and save them to decimal variables.Here is the code.(adult-number of adult tickets,child-number of child tickets,adprice-price of an adult ticket,chprice-price of a child ticket.)
adult= Double.Parse(txtadult.Text);
child = Double.Parse(txtchild.Text);
con.Open();
String select_query_pri = "SELECT Adult,Child FROM Price WHERE No= 1 ";
cmd = new SqlCommand(select_query_pri, con);
SqlDataReader R = cmd.ExecuteReader();
while (R.Read())
{
adprice = R.GetDouble(0);
chprice = R.GetDouble(1);
}
con.Close();
tot = (adult * adprice) + (child * chprice);
txttotal.Text = tot.ToString();
Then I'm using another double variable to calculate the total of the tickets and then it is displayed in the program.But when the program is executed,an error appears saying "Specified cast is not valid".
What is the reason for this error?

Try using the following lines;
adprice = Convert.ToDouble(R[0]);
chprice = Convert.ToDouble(R[1]);

Related

Iterate through one column in a datatable to find matching values, then add to list to output to view

I have data from an SQL table being shown in a view. The table has the following:
Authorise(AuthoriseID,TransactionID, TransactionName, AccountID, AccountName, Match)
The TransactionID and AccountID are repeated several times but only once together (They come from two different tables that has been joined through a matching function).
Currently I have an ActionResult HTTPGET which uses a stored proceudre to "Select * from Authorise order by TransactionID". Everything from the table is returned to the user. I only want rows for a certain TrnsactionID. The user then will accept or reject (sends the rows to other tables in the database). Once all the rows of that TransactionID are complete it will move to the next TransactionID and all the rows with that TransactionID. The rnsactionID will change so the first TransactionID displayed to the user just depends on what is the first ID.
My question is, how do I loop through one column in a datatable, get matching values, only display those rows and then move to the next ID once all rows have been authorised?
I know I would need to set the first TransactionID to a variable and then loop through the datatable, if any of the other values in that column match the variable then add to a list...I just cant seem to get it right. I have tried a few things and its not looking right. This is one attempt -
This is my code for the Controller (It all works when sending all data to the view):
public ActionResult Authorise()
{
SqlConnection con = new SqlConnection();
con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbpath"].ToString());
List<AuthoriseModel> AuthoriseList = new List<AuthoriseModel>();
SqlCommand com = new SqlCommand("GetAuthorise", con);
com.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(com);
DataTable dt = new DataTable();
con.Open();
da.Fill(dt);
con.Close();
foreach (DataRow dtRow in dt.Rows)
{
string CurrentUID = dtRow["TransactionID"].ToString();
if (dtRow["TransactionID"].ToString().Equals(CurrentUID))
{
AuthoriseList = (from DataRow dr in dt.Rows
select new AuthoriseModel()
{
AuthoriseID = Convert.ToInt32(dr["AuthoriseID"]),
TransactionID = Convert.ToInt32(dr["TransactionID"]),
TransactionName = Convert.ToString(dr["TransactionName"]),
AccountID = Convert.ToInt32(dr["AccountID"]),
AccountName = Convert.ToString(dr["AccountName"]),
PercentMatch = Convert.ToString(dr["PercentMatch])
}).ToList();
}
}
return View(AuthoriseList);
}
This list will then only display rows with that same TransactionID, once all rows have been dealt with and removed from then it will move to the next TransactionID?
Thanks in advance

Taking one value from a table

sorry if this has been asked before but I everything I found has not helped.
I'm looking to set a value from a table to the text property of a label. This is what I have so far:
In a separate class with the connection string "conn" -
(SQL Region)
Public Const SELECT_1 As String = "SELECT TOP 1 * FROM [TableTimes]
WHERE [timeID] = #PKey"
(Methods Region)
Public Shared Function returnOneRow(PrimaryKey As Integer) As TableTimes
Dim returnRow As New TableTimes(0)
Dim conn As New SqlConnection
conn.connectionstring = Conn.getConnectionString
Dim command As New SqlCommand
command.connection = conn
command.CommandType = CommandType.Text
command.CommandText = SQL.SELECT_1
command.Parameters.AddWithValue("#PKey", PrimaryKey)
Try
conn.Open()
Dim dR As IDataReader = command.ExecuteReader
If dR.Read() Then
returnRow.timeID = PK
If Not IsDBNull(dR(Fields.linkID)) Then returnRow.linkID = dR(Fields.linkID)
If Not IsDBNull(dR(Fields.dateTime)) Then returnRow.dateTime = dR(Fields.dateTime)
End If
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRow
End Function
And then back in the main form I am trying to set the dateTime to a label based on what primary key (timeID) I enter as a parameter. This is the closest I can think of:
label.Text = (Tables.TableTimes.returnOneRow(1).dateTime).ToString
I know the output should be "2016-02-04 10:00:00" for the row with the timeID of 1 based on my table data, but instead it returns "0001-01-01 12:00:00" no matter what parameter I enter.
I would prefer to not change my method or sql statement and just change how I call the function in the main form if that's possible.
Thank you!

Displaying multiple rows in multiple textboxes

I have a SQL Database table with multiple rows. I want to get the data from the rows based on the ID of that row and then present it in a certain textbox. I've got it working with Access 2013, but i've recently decided to move it to SQL.
I get an error
"There is already an open Datareader associated with this command"
Before i show you the code, it's pretty simplistic. I kind of "made" it work with access 2013, but SQL doesn't like it. The way the APP works it is paramount to have the data displayed in textboxes to make it easier to amend the data whilst being able to tab to the next box efficiently. That's why i haven't used Gridview. well, i have but that is for an asset register which is fine.
The code:
Try
conn.Open()
'***************** Populate Textboxes based on ID 1 row of PrinterDetails ***************** '
Dim sql1 As String
sql1 = "select * from PrinterDetails where ID=1"
cmd = New SQLCommand(sql1, conn)
reader = cmd.ExecuteReader
While reader.Read
'' Convert to string to prevent DBNULL errors
SNAME1.Text = reader.Item("SiteName").ToString
MAKE1.Text = reader.Item("Make").ToString
MODEL1.Text = reader.Item("Model").ToString
PRINTERIP1.Text = reader.Item("PrinterIP").ToString
PSERVER1.Text = reader.Item("Server").ToString
SHARE1.Text = reader.Item("Share").ToString
LOC1.Text = reader.Item("Location").ToString
UN1.Text = reader.Item("Username").ToString
PASS1.Text = reader.Item("Password").ToString
SUPPORT1.Text = reader.Item("Support").ToString
End While
'***************** Populate Textboxes based on ID 2 row of PrinterDetails ***************** '
Dim sql2 As String
sql2 = "select * from PrinterDetails where ID=2"
cmd = New SQLCommand(sql2, conn)
reader = cmd.ExecuteReader
While reader.Read
'' Convert to string to prevent DBNULL errors
SNAME2.Text = reader.Item("SiteName").ToString
MAKE2.Text = reader.Item("Make").ToString
MODEL2.Text = reader.Item("Model").ToString
PRINTERIP2.Text = reader.Item("PrinterIP").ToString
PSERVER2.Text = reader.Item("Server").ToString
SHARE2.Text = reader.Item("Share").ToString
LOC2.Text = reader.Item("Location").ToString
UN2.Text = reader.Item("Username").ToString
PASS2.Text = reader.Item("Password").ToString
SUPPORT2.Text = reader.Item("Support").ToString
End While
I've tried closing the connection and re-opening but that doesn't work.
Why such a bizarre query and code; your SQL query can simply be like below using a IN operator
select * from PrinterDetails where ID in (1,2);
BTW, for your issue check This MSDN Link specifically the Remarks section. In essence, you will need to close the already opened reader.

Get dates as check if it is ending

im in a project and now im stuck on this. I need to read from a query to sql somedates and is id, and if that date if ending(lets say 20days range) , i will write something like "The item with id=? will end in 20days"
So far i got this
SqlConnection myCon = new SqlConnection(connectionString);
SqlCommand myCommand = new SqlCommand();
myCommand.CommandText = "SELECT * FROM cmsPropertyData WHERE contentNodeId IN (SELECT contentNodeId FROm cmsPropertyData WHERE propertytypeid = 138 AND dataNtext LIKE '41')AND propertytypeid = 137 AND dataNtext IS NOT NULL AND dataNtext NOT LIKE ''";
myCommand.Connection = myCon;
myCon.Open();
SqlDataReader Reader;
Reader = myCommand.ExecuteReader();
while (Reader.Read())
{
string getdatas = Reader["dataNtext"].ToString();
Response.Write(getdatas);
}
But like this i get all the datas into one single string and i dont know even witch id she belongs to. Im problably doing the wrong way , so if someone can help i would appreciate :)
Well your query is not clear. But if you want to find out if a row within 20 days range or not you do the following:
SELECT * FROM cmsPropertyData WHERE DATEDIFF(dd,dataNtext,GETDATE()) <= 20

Remove repeated values from dataGridViewComboBoxColumn

I use DataGridViewComboBoxColumn to make a ComboBox in DataGridView but my ComboBox isn't good enough. I need my ComboBox to not have repeated values on it. This is an example:
Apple
Blackberry
Chrome
Apple
I want to remove the values that appear more than one time. How can I do that?
This is my code:
OleDbConnection conn = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();
Dataset data = new Dataset();
OleDbDataAdapter adapter = new OleDbDataAdapter();
string path = "Data Source = "+".\\"+"test.accdb";
string conStr = "Provider = Microsoft.ACE.OleDb.12.0;"+#path;
conn.Open();
string sql = "SELECT * FROM Table1;"
cmd = new OleDbCommand(sql,conn);
adapter = new OleDbDataAdapter(cmd);
data = new Dataset();
adapter.Fill(data,"Table1");
DataGridViewComboBoxColumn testcolumn = new DataGridViewComboBoxColumn();
testcolumn.Name = "test na ja";
testcolumn.Datasource = data.table[0];
testcolumn.ValueMember = "Remedy";
testcolumn.DisplayMember = "Remedy";
dataGridview1.Columns.Add(testcolumn);
conn.Close()
change the SELECT statement to return distinct values of remedy:
string sql = "SELECT DISTINCT remedy FROM Table1;"
and if you want it ordered:
string sql = "SELECT DISTINCT remedy FROM Table1 ORDER BY remedy ASC;"
or
string sql = "SELECT DISTINCT remedy FROM Table1 ORDER BY remedy DESC;"
As well as applying the distinct statement to your SQL it is possible to apply a distinct to the original DataTable when creating a second table as shown below (with a unit test and helper classes included that I used to prototype this).
I've added a comment below to highlight the line where the distinct is applied - what you use is the .ToTable() method which takes the Boolean parameter Distinct to specify only return distinct rows.
[TestMethod]
public void CreateDistinctDataTable()
{
DataTable originalTable = CreateDataTable();
AddDataToTable("Fred", "Bloggs", originalTable);
AddDataToTable("Fred", "Bloggs", originalTable);
AddDataToTable("John", "Doe", originalTable);
// This is the key line of code where we use the .ToTable() method
DataTable distinctTable = originalTable.DefaultView.ToTable( /*distinct*/ true);
// The original table has two rows with firstname of Fred
Assert.AreEqual(2, originalTable.Select("firstname = 'Fred'").Length);
// The new table only has one row with firstname of Fred
Assert.AreEqual(1, distinctTable.Select("firstname = 'Fred'").Length);
}
private DataTable CreateDataTable()
{
DataTable myDataTable = new DataTable();
DataColumn myDataColumn;
myDataColumn = new DataColumn();
myDataColumn.DataType = Type.GetType("System.String");
myDataColumn.ColumnName = "firstname";
myDataTable.Columns.Add(myDataColumn);
myDataColumn = new DataColumn();
myDataColumn.DataType = Type.GetType("System.String");
myDataColumn.ColumnName = "lastname";
myDataTable.Columns.Add(myDataColumn);
return myDataTable;
}
private void AddDataToTable(string firstname, string lastname, DataTable myTable)
{
DataRow row = myTable.NewRow();
row["firstname"] = firstname;
row["lastname"] = lastname;
myTable.Rows.Add(row);
}
One additional thought is I would suggest not selecting * from your table in the SQL statement. This can have performance implications down the track if more columns are added (particularly things like blobs) and could also mean you get columns that break the distinct nature of your query.