How to get a single string variable from SqlDataAdapter code - c#

I have this nifty code that takes selected data from a sql table and adds it to an email body. It will (thanks to the help of stack overflow geniuses) return multiple records and group them in the email body very nicely. Problem is - the email field. of course, it is in the For each loop and returns multiple instances of that record - which, in turn, writes to the To field in email. This record is always the same and I only want one instance written to my variable (eml). I'm guessing this would be simple - but I am not coming up with a good solution short of performing the query again.
string str = #"Data Source=srvr;Initial Catalog=db;Integrated
Security=True";
SqlConnection scn;
SqlDataAdapter da;
DataSet ds;
salesOrdersTableAdapter.SO(_TST_TWIDataSet.SalesOrders);
scn = new SqlConnection(str);
da = new SqlDataAdapter("SELECT DISTINCT DATEADD (dd, DATEDIFF(dd,0,ShipDate),0) AS ShipDate,RTRIM(SalesOrder) AS [Sales Order], RTRIM(PartNum) AS [Part Number]," +
"RTRIM(Description) AS Description,RTRIM(DueQty) AS Quantity,RTRIM(CustPartNum) AS[Customer Part No], RTRIM(CustPo) AS[Customer PO], " +
"RTRIM(CustRev) AS[Customer Rev], RTRIM(email) AS [Email] " +
"FROM tbl WHERE Ack <> 'Y'AND SalesOrder =" + MyGlobals.ord, scn);
ds = new DataSet();da.Fill(ds, "SalesOrders");
var orderListBody = new StringBuilder();
var sbj = string.Empty;
foreach (DataRow Row in ds.Tables["SalesOrders"].Rows)
{
orderListBody.Append("Order Number " + Row["Sales Order"] + "<br />");
orderListBody.Append("Part Number: " + Row["Part Number"] + "<br />");
orderListBody.Append("Description: " + Row["Description"] + "<br />");
orderListBody.Append("Customer Part Number: " + Row["Customer Part No"] + "<br />");
orderListBody.Append("Customer Revision: " + Row["Customer Rev"] + "<br />");
DateTime dte = DateTime.Now;
orderListBody.Append("Expected Ship Date: " + dte.ToShortDateString() + "<br />");
orderListBody.Append("Quantity: " + Row["Quantity"] + "<br />");
orderListBody.Append("<br />");
// eml += Row["Email"];
sbj = "Order Acknowledgement for your PO " + Row["Customer PO"];
}
thanks in advance

Just call ToString() on the object returned by the row indexer:
eml = Row["Email"].ToString();

Related

Inserting record into database column with auto number

I am trying to add a record to my database using the following function
The Error occurs at
adapter.InsertCommand.ExecuteNonQuery();
Full code:
public void Insert()
{
string query;
myDB.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(#"SELECT * From Eiendom", myDB);
query = #"INSERT INTO Eiendom (AreaID, AgentID, KlientID, AdresID, EiedomAantalBadkamers, EiedomAantalSlaapkamers, EiendomPrys, EiedomSwembad, EiedomGarages, EiedomAantalVloere, EiedomOppervlakte, EiedomTipePlan, EiedomAdisioneleInligting)
VALUES ('" + areaID + " , " + agentID + " , " + klientID + " , "
+ adressID + " , " + badkamers + " , " + slaapkamers + " , " + prys + " . "
+ " , " + swembad + " , " + garages + " , " + vloere + " , " + oppervlakte
+ " , " + plan + " , " + inligting + "')" ;
OleDbCommand insert = new OleDbCommand(query, myDB);
adapter.InsertCommand = insert;
adapter.InsertCommand.ExecuteNonQuery();
DataSet ds = new DataSet();
adapter.Fill(ds, "Eiendom");
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "Eiendom";
myDB.Close();
}
I get an error that says ;
System.Data.OleDb.OleDbException: 'Number of query values and destination fields are not the same.'
I actually do understand as to why this is presenting itself as I am not adding the autonumber column I have in my database
So what I'm asking is what can I do as a workaround to add the record but the auto number column fills itself in when adding the record?
You don't need to hand craft your InsertCommamd. The OleDbCommandBuilder can do it all for you. I think it should deal with Autonumbers.
var cbr = new OleDbCommandBuilder(adapter);
cbr.QuotePrefix = "[";
cbr.QuoteSuffix = "]";
adapter.InsertCommand = cbr.GetInsertCommand(true);

How can we format (grouping) email from SQL query?

I have code that I am running a SQL query to string variables and writing them to Outlook. The code works fine but I am having a bit of trouble when there is more than one result. Each result runs together in the email...
Present Result:
Thank you for your order!
Order Number 20016721Order Number 20016721
Part Number: NRE0000Part Number: PWR1812
Description: NRE ChargeDescription: High Power USB Charger
Customer Part Number:1234Customer Part Number:1234
Customer Revision:A Customer Revision: A
Expected Ship Date: 9/22/2017Expected Ship Date: 9/22/2017
Regards,
What I want:
Thank you for your order!
Order Number 20016721
Part Number: NRE0000
Description: NRE Charge
Customer Part Number: 1234
Customer Revision: A
Expected
Ship Date: 9/22/2017
Order Number 20016721
Part Number: PWR1812
Description: High
Power USB Charger
Customer Part Number:1234
Customer Revision: A
Expected Ship Date: 9/28/2017
Regards,
Here Is my Code:
string ord = "";
string pn = "";
string des = "";
string cpn = "";
string rev = "";
string esd = "";
string qty = "";
string eml = "";
string sbj = "";
string str = #"Data Source=my source;Initial Catalog=table;Integrated Security=True";
SqlConnection scn;
SqlDataAdapter da;
DataSet ds;
myTableAdapter.SO(_A_TWIDataSet.SalesOrders);
scn = new SqlConnection(str);
da = new SqlDataAdapter("SELECT DISTINCT DATEADD (dd, DATEDIFF(dd,0,ShipDate),0) AS ShipDate,RTRIM(SalesOrder) AS [Sales Order], RTRIM(PartNum) AS [Part Number]," +
"RTRIM(Description) AS Description,RTRIM(DueQty) AS Quantity,RTRIM(CustPartNum) AS[Customer Part No], RTRIM(CustPo) AS[Customer PO], " +
"RTRIM(CustRev) AS[Customer Rev], RTRIM(email) AS [Email] " +
"FROM SalesOrders WHERE Ack <> 'Y'AND SalesOrder =" + MyGlobals.ord, scn);
ds = new DataSet();da.Fill(ds, "SalesOrders");
foreach(DataRow Row in ds.Tables["SalesOrders"].Rows)
{
ord = ord + "Order Number "+ Row["Sales Order"];
pn = pn + "Part Number: " + Row["Part Number"];
des = des + "Description: " + Row["Description"];
cpn = cpn + "Customer Part Number: " + Row["Customer Part No"];
rev = rev + "Customer Revision: " + Row["Customer Rev"];
DateTime dte = DateTime.Now;
esd = esd + "Expected Ship Date: " + dte.ToShortDateString();
qty = qty + "Quantity: " + Row["Quantity"];
eml = eml + Row["Email"];
sbj = sbj + "Order Acknowledgement for your PO " + Row["Customer PO"];
}
try
{
//Must add Outlook Reference Object Library
Outlook.Application _app = new Outlook.Application();
Outlook.MailItem mail = (Outlook.MailItem)_app.CreateItem(Outlook.OlItemType.olMailItem);
mail.To = eml;
mail.BCC = ";CustomerService#touchstn.com";
mail.Subject = sbj;
mail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
mail.HTMLBody = "<HTML><BODY>";
mail.HTMLBody += "Thank you for your order!" + "<br />" + "<br />" + ord + "<br />" + pn +
"<br />" + des + "<br />" + cpn + "<br />" + rev + "<br />" + esd + "<br />"
+ "<br />"+ "Regards,"
mail.Display(true);
// mail.Send();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Thanks in advance
Update: Results form using the suggested code below (almost there!!)
Thank you for your order!
Order Number 20016721Part Number:
NRE0000Description: NRE ChargeCustomer Part Number: Customer Revision:
Expected Ship Date: 9/22/2017Quantity: 1Order Number 20016721Part
Number: PWR1812Description: High Power USB ChargerCustomer Part
Number: Customer Revision: Expected Ship Date: 9/22/2017Quantity: 400
Regards
,
What you need to do is create a one string with the order details in it with line breaks a proper places.
Consider following code.
using System.Text;
[...]
var orderListBody = new StringBuilder();
var eml = string.Empty;
var sbj = string.Empty;
foreach (DataRow Row in ds.Tables["SalesOrders"].Rows)
{
orderListBody.Append("Order Number " + Row["Sales Order"] + "<br />");
orderListBody.Append("Part Number: " + Row["Part Number"] + "<br />");
orderListBody.Append("Description: " + Row["Description"] + "<br />");
orderListBody.Append("Customer Part Number: " + Row["Customer Part No"] + "<br />");
orderListBody.Append("Customer Revision: " + Row["Customer Rev"] + "<br />");
DateTime dte = DateTime.Now;
orderListBody.Append("Expected Ship Date: " + dte.ToShortDateString() + "<br />");
orderListBody.Append("Quantity: " + Row["Quantity"] + "<br />");
orderListBody.Append("<br />"); //Adding extra line break between two orders.
eml = Row["Email"];
sbj = "Order Acknowledgement for your PO " + Row["Customer PO"] + "<br/>";
}
And HTMLBody should be set as following.
mail.To = eml;
mail.BCC = ";CustomerService#touchstn.com";
mail.Subject = sbj;
mail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
mail.HTMLBody = "<HTML><BODY>";
mail.HTMLBody += "Thank you for your order!" + "<br />" + orderListBody.ToString() + "<br />"+ "Regards," ;
This should resolve your issue.
What you are trying to do is simply appending multiple results in single variable in a loop. What I can gather from your example is that you have two different orders that need to be printed in the html body of outlook. For that you need to maintain different variables for each order (Not advisable). You can create a class of order specifics (such as ord, pn, des, cpn, rev, esd) and then use the class objects to store the values for each order specifics. (differtiate the orders on the basis of part numbers. (Take care of the code in for loop to be precise).
EDIT as requested:
Just an example below. Take care of the syntax wherever needed. (I typed this on my way home )
//your class specifics will go something like this..
class for order specifics
//your actual class where your main logic is there
your actual class where your main logic is there
This way may not be the most efficient on handling huge records but the code is cleaner. Hope this helps. Enjoy!

Using '#val3' or #val3 in SQL Server query parameters

I am just wondering what is the correct way for sending this old query statement:
"SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = 1 " +
"AND " +
"StartDate = " + Session["between"] + " " +
"AND " +
"UPPER(I1) = '" + Session["StrUser"].ToString().ToUpper() + "'"
To this way (correct way of passing the parameters):
SqlDataAdapter da = new SqlDataAdapter();
DataSet _ds1 = new DataSet();
String blah = "SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = #val1 " +
"AND " +
"StartDate #val2 " +
"AND " +
"UPPER(I1) = '#val3'"
command = new SqlCommand(blah, con);
command.Parameters.AddWithValue("#val1", 1);
command.Parameters.AddWithValue("#val2", Session["between"].ToString());
command.Parameters.AddWithValue("#val3", Session["StrUser"].ToString().ToUpper());
da = new SqlDataAdapter(command);
da.Fill(_ds1, dbName);
da.Dispose();
closeAllConnections();
command.Parameters.Clear();
return _ds1;
The main focus of this question is the '#val3'" part. Is that needed or will the command.Parameters.AddWithValue automatically place that if needed?
Using parameters is a good way of separating SQL code from data. As such, you should understand that the ' characters are part of a data literal. As such, unless you're wanting to compare I1 with the literal string #val3, and instead want to use the parameter, it should not be enclosed in 's.
This is correct:
String blah = "SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = #val1 " +
"AND " +
"StartDate = #val2 " +
"AND " +
"UPPER(I1) = #val3"
will the command.Parameters.AddWithValue automatically place that if needed?
No, it will not - because you're no longer trying to construct a literal value, no 's are required at all. Parameters aren't just a fancy way of doing text replacement - they keep the code and data separate and, importantly, deal with any required conversions behind the scenes.

Submit Dynamically generated inputs to SQL

I have a Java Script dynamically creating rows in a table when a contact is added. Each contact added I want to submit them to a cell in a sql database. I have no issues submitting the first contact but i need to use a loop (maybe a for loop?) to submit all of the contacts added to the dynamically created rows in the table. I am very new to the C# community and looking for a little help on how to do this.
When the rows are created via Java Script I also have it creating an input with a 'name' value, this name value is what is used to submit to the cell in the database.
Thanks in advance
Code is below:
JavaScript
function flNames() {
var rowID = parseInt(document.getElementById("ContactsRowCount").value, 10);
rowID++;
if (currentRow > 0) {
saveEdits();
} else {
var firstName = $("#firstName").val();
var lastName = $("#lastName").val();
var sHtml = "<tr id='row" + rowID + "'>" +
"<td class='tblStyle68wlb' id=\"FirstN" + rowID + "\">" + firstName + "</td><input type=\"hidden\" value=\"" + firstName + "\" name=\"cFirst\" />" +
"<td class='tblStyle68wl' id=\"LastN" + rowID + "\">" + lastName + "</td><input type=\"hidden\" value=\"" + lastName + "\" name=\"cLast\" />" +
"<td class='tblStyle68wl' ><button type='button' class='XsmallButtons' onclick='editRow(" + rowID + ")'>Edit</button></td>" +
"<td class='tblStyle68wlb' ><button type='button' class='XsmallButtons' onclick='deleteRow(" + rowID + ")'>Delete</button></td>" +
"</tr>";
$("#dynamicTableTesting").append(sHtml);
newRow++;
document.getElementById("ContactsRowCount").value = rowID;
$("#firstName, #lastName").val("");
}
}
C#
protected void Page_Load(object sender, EventArgs e)
{
GetFormData();
}
private void GetFormData()
{
string dynamicFirstName = Request.Form["cFirst"];
string dynamicLastName = Request.Form["cLast"];
string tableContactID = Request.Form[""];
string sql = #"
INSERT INTO
tableContactData
(
fName
,lName
)
VALUES
(
#cFirst
,#cLast
);
SELECT SCOPE_IDENTITY();
";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("cFirst", dynamicFirstName);
cmd.Parameters.AddWithValue("cLast", dynamicLastName);
conn.Open();
tableContactID = cmd.ExecuteScalar().ToString();
conn.Close();
}

Display all rows returned by SQL query in a div

I'm trying to output the result of my SQL query to a div using the InnerHTML. but I can't get more than one record to show up. How do I make it so that all of my records are displayed in the DIV? On my page I have the DIV contained within a UpdatePaneland I only 1 row is displayed even when the query returns more than one row.
string sql = "Select * From Events";
SqlCommand command = new SqlCommand(sql, conn);
command.CommandType = CommandType.Text;
conn.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
divout1.InnerHtml += "Name: " + reader["Name"].ToString() + "<br />" +
"Date: " + reader["Date"].ToString() + "<br />" +
"Location: " + reader["Location"].ToString() + "<br />";
divout.Visible = true;
}
Well, at first look, unless your query returns only one row, it should get all data on your div.
try to put a break point on the last bracket of your while statement and see what happens on your div after first iteration.
for other way, try to put the div out of the updatepanel to see what appens?
Why not use a StringBuilder to build your sql and then output the contents of the StringBuilder:
StringBuilder sb = new StringBuilder(1024);
string sql = "Select * From Events";
SqlCommand command = new SqlCommand(sql, conn);
command.CommandType = CommandType.Text;
conn.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
sb.AppendLine("Name: " + reader["Name"].ToString() + "<br />" +
"Date: " + reader["Date"].ToString() + "<br />" +
"Location: " + reader["Location"].ToString() + "<br />");
}
if(sb.Length > 0) {
divout.InnerHtml = sb.ToString();
divout.Visible = true;
}
Why not try something like this, may be concatenating inside the InnerHtml is screwing up or something. also be sure you really have more than one row.
var sb = new StringBuilder();
var formatString = "Name: {0} <br />Date: {1}<br />Location: {2}<br />";
while (reader.Read())
{
sb.AppendFormat(formatString, reader["Name"].ToString(), reader["Date"].ToString(), reader["Location"].ToString());
}
divout1.InnerHtml = sb.Tostring();
divout1.Visible = true;
Try:
string sql = "Select * From Events";
SqlCommand command = new SqlCommand(sql, conn);
command.CommandType = CommandType.Text;
conn.Open();
reader = command.ExecuteReader();
string s = string.Empty;
while (reader.Read())
{
s += "Name: " + reader["Name"].ToString() + "<br />" +
"Date: " + reader["Date"].ToString() + "<br />" +
"Location: " + reader["Location"].ToString() + "<br />";
}
divout1.innerHtml = s;
divout1.Visible = true;
You should probably encode the strings coming from the Database since you're directly outputting it as raw HTML.
divout1.InnerHtml += "Name: " + Server.HtmlEncode(reader["Name"].ToString()) + "<br />"
+ "Date: " + Server.HtmlEncode(reader["Date"].ToString()) + "<br />"
+ "Location: " + Server.HtmlEncode(reader["Location"].ToString()) + "<br />";
see HttpServerUtility.HtmlEncode

Categories

Resources