Split value from StringCollection to get as parameters - c#

how to split into a string array and pass them to command parameters or hiddenfield, just need to split the string "S0010M,AZI002M,3,12/26/2013 12:00:00 AM,VDIQ20"
to pass with parameters like
cmd.Parameters.AddWithValue("#DealerCode", "S0010M");
cmd.Parameters.AddWithValue("#Code", "AZI002M");
cmd.Parameters.AddWithValue("#Qty", 33);
cmd.Parameters.AddWithValue("#ExpireDate", "12/26/2015");
cmd.Parameters.AddWithValue("#BatchNumber", "VDIQ20");
i have big problem about this .. please can you help me to fix this , beaus still learning the subject..
after click on Return button , take the data from gridview, it can be more than one rows.
protected void btnReturn_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection SetDEL_Stores = new StringCollection();
if (ViewState["CurrentData"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
var DealerCode = HFDealerCode.Value;
var ItemIdentityCode = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[2].FindControl("ItemIdentityCode");
var Qty = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[8].FindControl("Quantity");
var ExpireDate = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[6].FindControl("ExpireDate");
var BatchNumber = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[7].FindControl("BatchNumber");
CultureInfo ci = new CultureInfo("en-GB");
SetDEL_Stores.Add(DealerCode + "," + ItemIdentityCode.Text + "," + decimal.Parse(Qty.Text) + "," + DateTime.ParseExact(ExpireDate.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture) + "," + BatchNumber.Text);
rowIndex++;
}
InsertDEL_Stores(SetDEL_Stores);
}
}
}
//in InsertDEL_Stores(SetDEL_Stores); event , taking the stringline separated with "," ,,
private void InsertDEL_Stores(StringCollection SC_PurLinr)
{
String strConnString = ConfigurationManager.ConnectionStrings["CBConnectionString"].ConnectionString;
DataSet ds = new DataSet();
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand("sp_DEL_Stores_IU", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DealerCode", SC_PurLinr[0]);
cmd.Parameters.AddWithValue("#Code", SC_PurLinr[1]);
cmd.Parameters.AddWithValue("#Qty", SC_PurLinr[2]);
cmd.Parameters.AddWithValue("#ExpireDate", SC_PurLinr[3]);
cmd.Parameters.AddWithValue("#BatchNumber", SC_PurLinr[4]);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}

It is not clear why you need a string collection first. If you want to keep the contents of the single rows in the GridView then start defining a class for your items where every single field is typed correctly (string for strings, numeric for numerics and datetime for dates) Copying the content of the grid in a string collection is just a waste of time and memory because every time you need to use the values stored in the string collection you need to find the correct string and split it to the individual fields.
I could just offer a pseudocode here because I haven't the possibility to test it.
(As an example I have named this class MyItem, but you could call it as you wish)
public class MyItem
{
public string DealerCode;
public string ItemCode;
public int Quantity;
public Datetime ExpireDate;
public string BatchNumber;
}
Then in your loop
// To keep the content of the grid keyed on the BatchNumber field
Dictionary<string, MyItem> items = new Dictionary<string, MyItem>();
for (int rowIndex = 0; i < dtCurrentTable.Rows.Count; i++)
{
MyItem itm = new MyItem();
itm.DealerCode = HFDealerCode.Value.ToString();
itm.ItemCode = GetGridValue(rowIndex, 2, "ItemIdentityCode");
itm.Quantity = Convert.ToDecimal(GetGridValue(rowIndex, 8, "Quantity");
itm.ExpireDate = Convert.ToDateTime(GetGridValue(rowIndex, 6, "ExpireDate");
itm.BatchNumber = GetGridValue(rowIndex, 7, "BatchNumber");
// Add the item to the dictionary for future reuses, however if you just want to store
// the item in the database this line is not needed
items.Add(itm.BatchNumber, itm);
// notice that the storing is executed inside the loop that extracts the values
// so every row is updated/inserted in the database
InsertDEL_Stores(itm);
}
GetGridValue is a method that you should write taking the parameters passed and returning a string with the value searched on the current row of your gridview. This could be simple as
string GetGridValue(int rowIndex, int cellIndex, string controlName)
{
Control c = GridViewSalesReturn.Rows[rowIndex].Cells[cellIndex].FindControl(controlName);
return (c != null ? c.Value.ToString() : "");
}
but you need to test it for its correctness.
However, after that you have an istance of MyItem class that you could store in the dictionary for future reuses or just pass it to the database working procedure
private void InsertDEL_Stores(MyItem itm)
{
String strConnString = ConfigurationManager.ConnectionStrings["CBConnectionString"].ConnectionString;
using(SqlConnection con = new SqlConnection(strConnString))
using(SqlCommand cmd = new SqlCommand("sp_DEL_Stores_IU", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DealerCode", itm.DealerCode);
cmd.Parameters.AddWithValue("#Code", itm.ItemCode);
cmd.Parameters.AddWithValue("#Qty", itm.Quantity);
cmd.Parameters.AddWithValue("#ExpireDate", itm.ExpireDate);
cmd.Parameters.AddWithValue("#BatchNumber", itm.BatchNumber);
con.Open();
cmd.ExecuteNonQuery();
}
}
I am aware that this code could raise more questions than the one that you try to resolve, neverless I think that this is more OOP than a simple string split

To split a string using commas as the separator character do the following
String[] values = str.split(",");
Then you can access the array in the following way
values[0];
But since your question is a bit confusing I suggest you read well the comments by other contributors what best suits your needs, how you are passing those values to the command parameters. Certainly, dictionaries and lists are more efficient than String collections

Related

Pass multiple string parameters to SQL Server procedure [duplicate]

This question already has answers here:
Passing a varchar full of comma delimited values to a SQL Server IN function
(27 answers)
Closed 5 years ago.
I have a stored procedure that uses the IN statement in the select condition.
SELECT *
FROM vwCashTransactions
WHERE TransactionTimeStamp BETWEEN '2017-01-30 ' AND '2017-12-01'
AND Country IN ('MY', 'BD')
ORDER BY TransactionTimeStamp DESC
I need to pass the country string from backend code.
This is the code I have written
if (manageCountries != null && manageCountries.Trim().Length > 0)
{
string[] words = manageCountries.Split(',');
string queryManageString = "";
int i = 0;
foreach (string word in words)
{
if (i != 0)
{
queryManageString += "','";
}
i++;
queryManageString += "'" + word + "'";
}
_DataTable = Global.DatabaseServices.GetTransactionReport("", startPeriod, endPeriod, queryManageString);
Somehow I am not getting the values. I am sure the issue is with the querymanageString. The way it is built is missing something. Can someone give an idea how I can achieve it?
Here's the code for calling the database:
public DataTable GetTransactionReport(string AccountCode, DateTime FromDate, DateTime ToDate, string ManagedCountry)
{
DataTable dataTable = new DataTable();
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.CommandText = "[GetTransactionReport]";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("#AccountCode", AccountCode);
sqlCommand.Parameters.AddWithValue("#FromDate", FromDate);
sqlCommand.Parameters.AddWithValue("#ToDate", ToDate);
sqlCommand.Parameters.AddWithValue("#ManagedCountry", ManagedCountry);
sqlCommand.CommandTimeout = 300;
ExecuteQuery(dataTable, sqlCommand);
sqlCommand.Dispose();
return dataTable;
}
public int ExecuteQuery(DataTable dt, SqlCommand cmd)
{
int rowCount = 0;
SqlDataAdapter da = null;
try
{
if (cmd.Connection == null)
cmd.Connection = GetSqlConnection();
da = new SqlDataAdapter();
da.SelectCommand = cmd;
rowCount = da.Fill(dt);
}
catch (Exception ex)
{
throw new DatabaseException(ex);
}
finally
{
cmd.Connection.Close();
cmd.Connection.Dispose();
cmd.Connection = null;
da.Dispose();
}
return rowCount;
}
It's not very clear how you pass the parameters, but it seems that you pass a delimited string. This will not work. Your procedure needs a list of country ids, not a string with a delimiter.
You can either do some magic in the stored procedure, splitting string and stuff like that, or create your own type.
Try something like this:
CREATE TYPE [dbo].[StringList] AS TABLE
([StringValue] [varchar](200) NULL)
Then your stored procedure has a parameter of type StringList, which can be used just like a normal table:
ALTER PROCEDURE [dbo].[MySproc]
#ids AS dbo.StringList READONLY
AS
BEGIN
SET NOCOUNT ON;
...etc..
And, finally, in your code use a DataTable for the values:
DataTable idsDT = new DataTable();
idsDT.Columns.Add("StringValue", typeof(string));
// fill datatable here
And the command parameter should be SqlDbType.Structured
var cmd = new SqlCommand(....)
SqlParameter countryParam = cmd.Parameter.AddWithValue("ids", idsDT);
countryParam.SqlDbType = SqlDbType.Structured;
It seems, there is something wrong in your for loop where you create comma seperated single quote string. Update for loop with below:
string[] words = manageCountries.Split(',');
string queryManageString = "";
int i = 0;
foreach (string word in words)
{
if (i != 0)
{
queryManageString += ",'" + word + "'";
}
else
{
queryManageString += "'" + word + "'";
}
i++;
}
OR if you don't want to go with for loop, here is one line solution
queryManageString = string.Join(",", words.Select(x => string.Format("'{0}'", x)));

C# - Non-latin characters doesnt appear properly in database Visual Studio

Here is my code which inserts into database the elements in the textboxes of a dynamic gridview. The code works perfectly but my problem is that the inserted elements that are typed in non-latin characters (greek characters) does not appear propely in database and instead they appear like that:
http://i.stack.imgur.com/pwVTf.jpg
Please can you tell me what to do in order to insert the greek characters properly? Here is the code:
private void InsertRecords(StringCollection sc)
{
StringBuilder sb = new StringBuilder(string.Empty);
string[] splitItems = null;
const string sqlStatement = "INSERT INTO P_interventions (Date,P_Id,Simeio,Aitio,Etos,Therap) VALUES";
int id = Convert.ToInt32(Session["pa_id"]);
foreach (string item in sc)
{
if (item.Contains(","))
{
splitItems = item.Split(",".ToCharArray());
sb.AppendFormat("{0}(#Date, #p_id ,'{1}','{2}','{3}','{4}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3]);
}
}
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand(sb.ToString(), connection))
{
cmd.Parameters.AddWithValue("#p_id", id);
cmd.Parameters.AddWithValue("#Date", DateTime.Now.ToShortDateString());
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
lblMessage.ForeColor = System.Drawing.Color.Green;
lblMessage.Text = "The records have benn inserted successfuly!";
}
protected void BtnSave_Click(object sender, EventArgs e)
{
//εγχειρήσεις
int rowIndex = 0;
StringCollection sc = new StringCollection();
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[4].FindControl("DropDownList2");
//get the values from TextBox and DropDownList
//then add it to the collections with a comma "," as the delimited values
sc.Add(string.Format("{0},{1},{2},{3}", box1.Text, box2.Text, box3.Text, ddl2.SelectedItem.Text));
rowIndex++;
}
//Call the method for executing inserts
InsertRecords(sc);
}
}
Since you use nchar fields in your database (as mentioned in a comment), your database already supports Unicode strings. However, you are passing the values you want to insert as non-Unicode string literals in your SQL:
'...'
You need to pass them as Unicode strings:
N'...'
Now don't just put an N in front of your string literals: There's something else you are doing wrong: You are passing user-supplied values by string concatenation, which is a serious security and stability issue. Use parameters instead - you already know how to work with parameters, since you do it for #p_id and #Date. Do the same for your string values. This will also fix the Unicode issue, since AddWithValue defaults to a Unicode parameter type for strings.
I think you have to use the Unicode data types in the database instead of the regular ones (ex:instead of Varchar use NVarchar).
Also in the your code use the N before the string fields Like
sb.AppendFormat("{0}(#Date, #p_id ,N'{1}',N'{2}',N'{3}',N'{4}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3]);

How to get the character and operator in a string in C# using Split

I have requirement where I have to perform calculation on textbox based on formula. I wanted to know how to get the field name and operators separately so that i can bind it in formula textbox. Example : {FieldName1} + {FieldName2}+{Fieldname3} is the formula and i want the data which contains braces separately as they will taken as field name and + symbol separately. I dont know how to get this. Here is my code-
DataTable dt_main = GetTable();
DataTable dt_AutocalculatedColumns = GetCalculatedColumn();
string AutoGeneratedColumnName = string.Empty;
string Formula = string.Empty;
string FLD1 = string.Empty;
string FLD2 = string.Empty;
string FLD3 = string.Empty;
if (dt_AutocalculatedColumns.Rows.Count > 0)
{
foreach (DataRow row_field in dt_AutocalculatedColumns.Rows)
{
AutoGeneratedColumnName = row_field["FieldName"].ToString();
Formula = row_field["AutoCalculatedFormula"].ToString();
string[] words = Formula.Split(' ');
foreach (string Eachword in words)
{
// what to do here i am not getting
}
}
}
protected DataTable GetCalculatedColumn()
{
SqlConnection con= newSqlConnection(ConfigurationManager.ConnectionStrings["ExcelLikeConnnectionString"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("My Select Query", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
con.Close();
return dt;
}
Any help would be appreciated. Thanks in advance
If you're using only + operator then you should split on it and not on ' '. To make sure that you don't have field name with spaces use trim.
string[] words = Formula.Split('+');
for (int i = 0; i < words.Length; i++)
{
words[i] = words[i].Trim();
}
Of course in this situation you can't have + in field names.
You can also use LINQ:
string formula = "{FieldName1} + {FieldName2}+{Fieldname3}";
string[] words = formula.Split('+')
.Select(w => w.Trim(new char[] {' ', '{', '}'})).ToArray();
This will split the string formula and trim each entry so that you are just left with your field names. The resulting output would be a 3 element array containing FieldName1, FieldName2, and FieldName3.

Add full row to DataTable MVC4

i'm new to MVC and I am trying to build a DataTable from a stored procedure response and pass it back to my View. For the rows I build a comma delimited string full of cell values.
The issue I am having is that the string is not getting parsed by the commas, and effectively it is passing the whole string into the first cell of each row.
What is the correct way to build up a row comprised of the individual values for each column? The number of columns, their names, and amount of records returned are all variable.
public ActionResult dataSet(string table, string key, string search)
{
SqlDataReader rdr = null;
SqlConnection con = new SqlConnection("Connection stuff");
SqlCommand cmd = new SqlCommand();
cmd = new SqlCommand("dbo.USP_getDataSet", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#key", key);
cmd.Parameters.AddWithValue("#table", table);
cmd.Parameters.AddWithValue("#search", search);
con.Open();
DataTable theTable = new DataTable();
try
{
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
int count = rdr.FieldCount;
string rowString = "";
int intRows = theTable.Columns.Count;
//Build columns on first pass through
if (intRows == 0){
for (int i = 0; i < count; i++){
theTable.Columns.Add(Convert.ToString(rdr.GetName(i).TrimEnd()), typeof(string));
}
}
//Grab all values for each column
for (int i = 0; i < count; i++){
rowString += '\"' + (Convert.ToString(rdr.GetValue(i)).TrimEnd()) + '\"' + ", ";
}
//Remove trailing delimiter
string finishedRow = rowString.Substring(0, rowString.Length - 2);
//Add the full row for each time through reader
theTable.Rows.Add(finishedRow);
}
}
finally
{
if (rdr != null)
{ rdr.Close(); }
if (con != null)
{ con.Close(); }
}
return View(theTable);
}
According to the documentation for the DataRowCollection.Add(params Object[] values) method, each value passed in will populate each cell. Since you are passing in a single value, it is the value of the cell.
You probably want:
var cells = new object[count];
for (int i = 0; i < count; i++)
{
cells[i] = rdr.GetString(i).Trim() + "\"
}
theTable.Rows.Add(cells)

Splitting the data in ASP.NET

I am trying to display a column from my local database into a dropdown list. The problem is that I would need to split the data so that they are not displayed all in one line. I have used the ";" to separate the data and then using the split(";") method to split them. I have tried the code that I've wrote below but it's not working. Any help will be appreciated.
public string DisplayTopicNames()
{
string topicNames = "";
// declare the connection string
string database = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Forum.accdb;Persist Security Info=True";
// Initialise the connection
OleDbConnection myConn = new OleDbConnection(database);
//Query
string queryStr = "SELECT TopicName FROM Topics";
// Create a command object
OleDbCommand myCommand = new OleDbCommand(queryStr, myConn);
// Open the connection
myCommand.Connection.Open();
// Execute the command
OleDbDataReader myDataReader = myCommand.ExecuteReader();
// Extract the results
while (myDataReader.Read())
{
for (int i = 0; i < myDataReader.FieldCount; i++)
topicNames += myDataReader.GetValue(i) + " ";
topicNames += ";";
}
//Because the topicNames are seperated by a semicolon, I would have to split it using the split()
string[] splittedTopicNames = topicNames.Split(';');
// close the connection
myCommand.Connection.Close();
return Convert.ToString(splittedTopicNames);
}
You are returning just one column from the table.
There is no reason to use a for loop over a field count (it is always 1)
Instead you could use a List(Of String) to save the values returned by the rows found.
Then return this list to use as datasource for your DropDownList
List<string> topicNames = new List<string>();
// Extract the results
while (myDataReader.Read())
{
topicNames.Add(myDataReader.GetValue(0).ToString();
}
....
return topicNames;
However it is not clear if the field TopicName contains itself strings separated by semicolon.
In this case you could write:
List<string> topicNames = new List<string>();
// Extract the results
while (myDataReader.Read())
{
string[] topics = myDataReader.GetValue(0).ToString().Split(';')
topicNames.AddRange(topics);
}
...
return topicNames;
if you prefer to return an array of strings then it is just a matter to convert the list to an array
return topicNames.ToArray();
EDIT
Of course returning an array or a List(Of String) requires changes to the return value of your method
public List<string> DisplayTopicNames()
{
......
}
or
public string[] DisplayTopicNames()
{
......
}
if you still prefer to return a string separated by semicolons then change the return statement in this way
return string.Join(";", topicNames.ToArra());
Unless I've lost my mind, something like this should work:
while (myDataReader.Read())
{
for (int i = 0; i < myDataReader.FieldCount; i++)
ddl.Items.Add(myDataReader.GetValue(i))
}
where ddl is the name of your DropDownList. If your ddl isn't available here, then add them to a List<string> collection instead and return that. And then this code may now become irrelevant:
//Because the topicNames are seperated by a semicolon, I would have to split it using the split()
string[] splittedTopicNames = topicNames.Split(';');
// close the connection
myCommand.Connection.Close();
return Convert.ToString(splittedTopicNames);
but, on top of all this I want to restructure the code for you a little because you need to be leveraging things like using.
public string DisplayTopicNames()
{
string topicNames = "";
// declare the connection string
string database = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Forum.accdb;Persist Security Info=True";
// Initialise the connection
using (OleDbConnection myConn = new OleDbConnection(database))
{
myConn.Open();
// Create a command object
OleDbCommand myCommand = new OleDbCommand("SELECT TopicName FROM Topics", myConn);
// Execute the command
using (OleDbDataReader myDataReader = myCommand.ExecuteReader())
{
// Extract the results
while (myDataReader.Read())
{
for (int i = 0; i < myDataReader.FieldCount; i++)
{
ddl.Items.Add(myDataReader.GetValue(i));
}
}
}
}
// not sure anything needs returned here anymore
// but you'll have to evaluate that
return "";
}
The reason you want to leverage the using statement is to ensure that unmanaged resources that exist in the DataReader and Connection get disposed properly. When leaving the using statement it will automatically call Dispose on the object. This statement is only used for objects that implement IDisposable.
I think this should work:
public List<string> DisplayTopicNames()
{
List<string> topics = new List<string>();
// Initialise the connection
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Forum.accdb;Persist Security Info=True");
OleDbCommand cmd = new OleDbCommand("SELECT TopicName FROM Topics");
using(conn)
using(cmd)
{
cmd.Connection.Open();
// Execute the command
using(OleDbDataReader myDataReader = cmd.ExecuteReader())
{
// Extract the results
while(myDataReader.Read())
{
topics.Add(myDataReader.GetValue(0).ToString());
}
}
}
return topics;
}

Categories