I have this app where i get data from a TextBox, insert it into a List<> and then display a new line in the CheckBoxList.
Example:
List<string> quantidade = new List<string>();
for (int i = 0; i < CheckBoxListLinhas.Items.Count; i++)
{
quantidade.Add(TextBoxQuantidade.Text.ToString());
}
List<string> artigo = new List<string>();
for (int i = 0; i < CheckBoxListLinhas.Items.Count; i++)
{
artigo.Add(TextBoxArtigo.Text.ToString());
}
List<string> valor = new List<string>();
for (int i = 0; i < CheckBoxListLinhas.Items.Count; i++)
{
valor.Add(TextBoxValor.Text.ToString());
}
/*List<string> artigo = new List<string>();
for (int i = 0; i < CheckBoxListLinhas.Items.Count; i++)
{
artigo.Add(TextBoxArtigo.Text.ToString());
}*/
CheckBoxListLinhas.Items.Add(new ListItem("Quantidade: " + TextBoxQuantidade.Text + " Artigo: " + TextBoxArtigo.Text + " Valor: " + TextBoxValor.Text) + " Anexo: " + FileUpload1.FileName.ToString());
And then I want to insert every row from that List<> to the database and I already have this example:
SqlCommand sqlInsertList = new SqlCommand("Insert into linhas (quantidade,descricao,valor) VALUES(#quantidade,#descricao,#valor)", sqlConn);
sqlInsertList.Parameters.AddWithValue("#quantidade", );
sqlInsertList.Parameters.AddWithValue("#descricao", TextBoxArtigo.Text);
sqlInsertList.Parameters.AddWithValue("#valor", float.Parse(TextBoxValor.Text, CultureInfo.InvariantCulture.NumberFormat));
sqlConn.Open();
sqlTran = sqlConn.BeginTransaction();
sqlInsert.Transaction = sqlTran;
sqlInsert.ExecuteNonQuery();
sqlTran.Commit();
What is the easiest way I can do that and adapt my SQLInsert?
SqlCommand sqlInsertList = new SqlCommand("Insert into linhas (quantidade,descricao,valor) VALUES(#quantidade,#descricao,#valor)", sqlConn);
sqlConn.Open();
sqlTran = sqlConn.BeginTransaction();
for (int i = 0; i < quantidade.Count; i++)
{
sqlInsertList.Transaction = sqlTran;
sqlInsertList.Parameters.Clear();
sqlInsertList.Parameters.AddWithValue("#quantidade", quantidade[i]);
sqlInsertList.Parameters.AddWithValue("#descricao", artigo[i]);
sqlInsertList.Parameters.AddWithValue("#valor", loat.Parse(valor[i], CultureInfo.InvariantCulture.NumberFormat));
sqlInsertList.ExecuteNonQuery();
}
sqlTran.Commit();
Related
ListViewItem item = new ListViewItem();
string productname = "";
conn = new MySqlConnection();
conn.ConnectionString = connString;
conn.Open();
string queryssxxxqbb = "Select * from products where deleted='No'";
MySqlCommand cmdaaxxxqbb = new MySqlCommand(queryssxxxqbb, conn);
MySqlDataReader dataReaderxxxxxqbb = cmdaaxxxqbb.ExecuteReader();
while (dataReaderxxxxxqbb.Read())
{
productname = dataReaderxxxxxqbb["productname"].ToString();
string productprice = dataReaderxxxxxqbb["productprice"].ToString();
string picturelink = dataReaderxxxxxqbb["picturelink"].ToString();
try
{
this.imageList1.Images.Add(Image.FromFile(#"\\" +
Properties.Settings.Default.Local_Server +
"\\Documents\\Stock And Inventory Software\\Product Pictures\\" +
picturelink));
}
catch
{
this.imageList1.Images.Add(Properties.Resources.default_image);
}
this.listView1.View = View.LargeIcon;
this.imageList1.ImageSize = new Size(100, 90);
this.listView1.LargeImageList = this.imageList1;
item.Text = productname;
}
conn.Close();
for (int j = 0; j < this.imageList1.Images.Count; j++)
{
item.BackColor = Color.White;
item.ImageIndex = j;
listView1.Items.Add(item);
}
Can anyone help me out, i keep getting "Cannot add or insert the item 'productname' in more than one place. You must first remove it from its current location or clone it."
I am trying to add the product name to much the images in a while loop.
You are continuously changing the value of item.Text, then iterating over all the images, but adding the same item value.
using(var conn = new MySqlConnection())
{
var index = 0;
conn.ConnectionString = connString;
conn.Open();
string queryssxxxqbb = "Select * from products where deleted='No'";
MySqlCommand cmdaaxxxqbb = new MySqlCommand(queryssxxxqbb, conn);
MySqlDataReader dataReaderxxxxxqbb = cmdaaxxxqbb.ExecuteReader();
while (dataReaderxxxxxqbb.Read())
{
var productname = dataReaderxxxxxqbb["productname"].ToString();
var productprice = dataReaderxxxxxqbb["productprice"].ToString();
var picturelink = dataReaderxxxxxqbb["picturelink"].ToString();
try
{
this.imageList1.Images.Add(Image.FromFile(#"\\" +
Properties.Settings.Default.Local_Server +
"\\Documents\\Stock And Inventory Software\\Product Pictures\\" +
picturelink));
}
catch
{
this.imageList1.Images.Add(Properties.Resources.default_image);
}
this.listView1.View = View.LargeIcon;
this.imageList1.ImageSize = new Size(100, 90);
this.listView1.LargeImageList = this.imageList1;
var item = new ListViewItem();
item.Text = productname;
item.BackColor = Color.White;
item.ImageIndex = index++;
listView1.Items.Add(item);
}
}
How can I pass multiple stored procedures to my Scripttask C# code in SSIS and generate output files?
I am successfully able to run one stored procedure from SQL Server database and output one file.
public void Main()
{
string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
try
{
string FileNamePart = Dts.Variables["User::FlatFileNamePart"].Value.ToString();
string DestinationFolder = Dts.Variables["User::DestinationFolder"].Value.ToString();
string StoredProcedureFig1_1 = Dts.Variables["User::StoredProcedureFig1_1"].Value.ToString();
string StoredProcedureFig1_2 = Dts.Variables["User::StoredProcedureFig1_2"].Value.ToString();
string FileDelimiter = Dts.Variables["User::FileDelimiter"].Value.ToString();
string FileExtension = Dts.Variables["User::FileExtension"].Value.ToString();
// USE ADO.NET Connection from SSIS Package to get data from table
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["localhost.onramps_tacc"].AcquireConnection(Dts.Transaction) as SqlConnection);
// Execute stored procedure and save results in data table
string query1 = "EXEC " + StoredProcedureFig1_1;
// how to run below query too? Stackoverflow question
string query2 = "EXEC " + StoredProcedureFig1_2;
SqlCommand cmd = new SqlCommand(query1, myADONETConnection);
DataTable d_table = new DataTable();
d_table.Load(cmd.ExecuteReader());
myADONETConnection.Close();
string FileFullPath = DestinationFolder + "\\" + FileNamePart + "_" + datetime + FileExtension;
StreamWriter sw = null;
sw = new StreamWriter(FileFullPath, false);
// Write the Header Row to File
String var = d_table + "i";
int ColumnCount = var.Columns.Count;
for (int ic = 0; ic < ColumnCount; ic++)
{
sw.Write(d_table.Columns[ic]);
if (ic < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
// Write all rows to the file
foreach (DataRow dr in d_table.Rows)
{
for (int ir = 0; ir < ColumnCount; ir++)
{
if (!Convert.IsDBNull(dr[ir]))
{
sw.Write(dr[ir].ToString());
}
if (ir < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
}
sw.Close();
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception exception)
{
// Create Log File for Errors
using (StreamWriter sw = File.CreateText(Dts.Variables["User::LogFolder"].Value.ToString() + "\\" +
"ErrorLog_" + datetime + ".log"))
{
sw.WriteLine(exception.ToString());
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Actual:
one stored procedure as input and output the columns and rows in one O/P file OR error file.
Expected:
Accept multiple stored procedures and corresponding generate OutputFiles and error files
Solution:
public void Main()
{
// TODO: Add your code here
string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
try
{
//Declare Variables
string FileNamePart = Dts.Variables["User::FlatFileNamePart"].Value.ToString();
string DestinationFolder = Dts.Variables["User::DestinationFolder"].Value.ToString();
string StoredProcedureFig1_1 = Dts.Variables["User::StoredProcedureFig1_1"].Value.ToString();
string StoredProcedureFig1_2 = Dts.Variables["User::StoredProcedureFig1_2"].Value.ToString();
string FileDelimiter = Dts.Variables["User::FileDelimiter"].Value.ToString();
string FileExtension = Dts.Variables["User::FileExtension"].Value.ToString();
//USE ADO.NET Connection from SSIS Package to get data from table
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["localhost.onramps_tacc"].AcquireConnection(Dts.Transaction)
as SqlConnection);
//Execute Stored Procedure and save results in data table
string query1 = "EXEC " + StoredProcedureFig1_1;
string query2 = "EXEC " + StoredProcedureFig1_2;
SqlCommand cmd1 = new SqlCommand(query1, myADONETConnection);
SqlCommand cmd2 = new SqlCommand(query2, myADONETConnection);
DataSet dset = new DataSet();
DataTable d_table1 = dset.Tables.Add("Fig1_1");
DataTable d_table2 = dset.Tables.Add("Fig1_2");
d_table1.Load(cmd1.ExecuteReader());
d_table2.Load(cmd2.ExecuteReader());
myADONETConnection.Close();
foreach (DataTable table in dset.Tables)
{
string FileFullPath = DestinationFolder + "\\" + FileNamePart + "_" + table + datetime + FileExtension;
StreamWriter sw = null;
sw = new StreamWriter(FileFullPath, false);
// Write the Header Row to File
int ColumnCount = table.Columns.Count;
for (int ic = 0; ic < ColumnCount; ic++)
{
sw.Write(table.Columns[ic]);
if (ic < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
// Write All Rows to the File
foreach (DataRow dr in table.Rows)
{
for (int ir = 0; ir < ColumnCount; ir++)
{
if (!Convert.IsDBNull(dr[ir]))
{
sw.Write(dr[ir].ToString());
}
if (ir < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
}
sw.Close();
Dts.TaskResult = (int)ScriptResults.Success;
}
}
I'm generating a csv file from an SqlDataReader, however it is not writing the column names, how can I make it write them? The code I'm using is as follows:
SqlConnection conn = new SqlConnection(myconn);
SqlCommand cmd = new SqlCommand("dbo.test", conn);
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
StreamWriter sw = new StreamWriter(myfilePath + "testfile.csv");
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string value = reader[i].ToString();
if (value.Contains(","))
value = "\"" + value + "\"";
sb.Append(value.Replace(Environment.NewLine, " ") + ",");
}
sb.Length--; // Remove the last comma
sb.AppendLine();
}
conn.Close();
sw.Write(sb.ToString());
sw.Close();
Read all the column names and append it to sb then iterate reader.
SqlDataReader reader = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
//Get All column
var columnNames = Enumerable.Range(0, reader.FieldCount)
.Select(reader.GetName) //OR .Select("\""+ reader.GetName"\"")
.ToList();
//Create headers
sb.Append(string.Join(",", columnNames));
//Append Line
sb.AppendLine();
while (reader.Read())
....
Using this solution i created an extension.
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="filename"></param>
/// <param name="path">if null/empty will use IO.Path.GetTempPath()</param>
/// <param name="extension">will use csv by default</param>
public static void ToCsv(this IDataReader reader, string filename, string path = null, string extension = "csv")
{
int nextResult = 0;
do
{
var filePath = Path.Combine(string.IsNullOrEmpty(path) ? Path.GetTempPath() : path, string.Format("{0}.{1}", filename, extension));
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.WriteLine(string.Join(",", Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList()));
int count = 0;
while (reader.Read())
{
writer.WriteLine(string.Join(",", Enumerable.Range(0, reader.FieldCount).Select(reader.GetValue).ToList()));
if (++count % 100 == 0)
{
writer.Flush();
}
}
}
filename = string.Format("{0}-{1}", filename, ++nextResult);
}
while (reader.NextResult());
}
You can use SqlDataReader.GetName to get the column name
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
}
Also you can create an extension method like below:
public static List<string> ToCSV(this IDataReader dataReader, bool includeHeaderAsFirstRow, string separator)
{
List<string> csvRows = new List<string>();
StringBuilder sb = null;
if (includeHeaderAsFirstRow)
{
sb = new StringBuilder();
for (int index = 0; index < dataReader.FieldCount; index++)
{
if (dataReader.GetName(index) != null)
sb.Append(dataReader.GetName(index));
if (index < dataReader.FieldCount - 1)
sb.Append(separator);
}
csvRows.Add(sb.ToString());
}
while (dataReader.Read())
{
sb = new StringBuilder();
for (int index = 0; index < dataReader.FieldCount - 1; index++)
{
if (!dataReader.IsDBNull(index))
{
string value = dataReader.GetValue(index).ToString();
if (dataReader.GetFieldType(index) == typeof(String))
{
//If double quotes are used in value, ensure each are replaced but 2.
if (value.IndexOf("\"") >= 0)
value = value.Replace("\"", "\"\"");
//If separtor are is in value, ensure it is put in double quotes.
if (value.IndexOf(separator) >= 0)
value = "\"" + value + "\"";
}
sb.Append(value);
}
if (index < dataReader.FieldCount - 1)
sb.Append(separator);
}
if (!dataReader.IsDBNull(dataReader.FieldCount - 1))
sb.Append(dataReader.GetValue(dataReader.FieldCount - 1).ToString().Replace(separator, " "));
csvRows.Add(sb.ToString());
}
dataReader.Close();
sb = null;
return csvRows;
}
Example:
List<string> rows = null;
using (SqlDataReader dataReader = command.ExecuteReader())
{
rows = dataReader.ToCSV(includeHeadersAsFirstRow, separator);
dataReader.Close();
}
You can use the SqlDataReader.GetName method to get the name of a column, like this:
for(int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
}
I developed following high performance extension
static void Main(string[] args)
{
SqlConnection sqlCon = new SqlConnection("Removed");
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("Select * from Table", sqlCon);
SqlDataReader reader = sqlCmd.ExecuteReader();
string csv=reader.ToCSVHighPerformance(true);
File.WriteAllText("Test.CSV", csv);
reader.Close();
sqlCon.Close();
}
Extention:
public static string ToCSVHighPerformance(this IDataReader dataReader, bool includeHeaderAsFirstRow = true,
string separator = ",")
{
DataTable dataTable = new DataTable();
StringBuilder csvRows = new StringBuilder();
string row = "";
int columns ;
try
{
dataTable.Load(dataReader);
columns= dataTable.Columns.Count;
//Create Header
if (includeHeaderAsFirstRow)
{
for (int index = 0; index < columns; index++)
{
row += (dataTable.Columns[index]);
if (index < columns - 1)
row += (separator);
}
row += (Environment.NewLine);
}
csvRows.Append(row);
//Create Rows
for (int rowIndex = 0; rowIndex < dataTable.Rows.Count; rowIndex++)
{
row = "";
//Row
for (int index = 0; index < columns - 1; index++)
{
string value = dataTable.Rows[rowIndex][index].ToString();
//If type of field is string
if (dataTable.Rows[rowIndex][index] is string)
{
//If double quotes are used in value, ensure each are replaced by double quotes.
if (value.IndexOf("\"") >= 0)
value = value.Replace("\"", "\"\"");
//If separtor are is in value, ensure it is put in double quotes.
if (value.IndexOf(separator) >= 0)
value = "\"" + value + "\"";
//If string contain new line character
while (value.Contains("\r"))
{
value = value.Replace("\r", "");
}
while (value.Contains("\n"))
{
value = value.Replace("\n", "");
}
}
row += value;
if (index < columns - 1)
row += separator;
}
dataTable.Rows[rowIndex][columns - 1].ToString().ToString().Replace(separator, " ");
row += Environment.NewLine;
csvRows.Append(row);
}
}
catch (Exception ex)
{
throw ex;
}
return csvRows.ToString();
}
Please see the below code which I use for writing to a text file. But database fetches nearly 1 millions records, so can someone please advise a faster way to do this or how should I change the below mentioned code to get it working faster?
try
{
using (OleDbConnection connection = new OleDbConnection(ConnectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
StreamWriter writer = new StreamWriter(FilePath + FileName);
var result = string.Empty;
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
result += dt.Rows[i][j] + "|";
}
result += "\r\n";
}
writer.WriteLine(result);
reader.Close();
writer.Close();
Dts.TaskResult = (int)ScriptResults.Success;
}
}
You load 1 million records in a datatable and then loop again on that table to write each row.
Probably you could do the same thing, but in half the time if you read a single row and write it down:
OleDbDataReader reader = command.ExecuteReader();
StreamWriter writer = new StreamWriter(FilePath + FileName);
var result = string.Empty;
while(reader.Read())
{
for (int j = 0; j < reader.FieldCount; j++)
{
result += reader[j] + "|";
}
result += "\r\n";
}
writer.WriteLine(result);
Also, using a StringBuilder to buffer your read in memory and not constantly writing to disk could be very beneficial in this situation:
// This size is just for example purpose. Should be fine tuned
StringBuilder buffer = new StringBuilder(1048576);
while(reader.Read())
{
for (int j = 0; j < reader.FieldCount; j++)
{
buffer.Append(reader[j] + "|");
}
buffer.AppendLine();
if(buffer.Length > 1048576 - 1024)
{
writer.Write(buffer.ToString());
buffer.Length = 0;
}
}
writer.Write(buffer.ToString());
MessageBox.Show(urls[m]);
of the code below it show 16 time like a,a,a,a,b,b,b,b,c,c,c,c,d,d,d,d how can i add 4 non duplicate to urls[m]. My code is purpose to swlwct url from data base to open on 4 different browser1 browser 2 .. but on browser show the same URL
namespace tabcontrolweb
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string MyConString = "SERVER=192.168.0.78;" +
"DATABASE=webboard;" +
"UID=aimja;" +
"PASSWORD=aimjawork;" +
"charset=utf8;";
MySqlConnection connection = new MySqlConnection(MyConString);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
command.CommandText = "SELECT urlwebboard FROM `listweb` WHERE `urlwebboard` IS NOT NULL AND ( `webbordkind` = 'เว็บท้องถิ่น' ) and `nourl`= 'n' order by province, amphore limit 4 ";
connection.Open();
Reader = command.ExecuteReader();
string[] urls = new string[4];
string thisrow = "";
string sumthisrow = "";
while (Reader.Read())
{
thisrow = "";
for (int i = 0; i < Reader.FieldCount; i++)
{
thisrow += Reader.GetValue(i).ToString();
System.IO.File.AppendAllText(#"C:\file.txt", thisrow + " " + Environment.NewLine);
sumthisrow = Reader.GetValue(i).ToString();
}
for (int m = 0; m < 4 ; m++)
{
urls[m] = sumthisrow;
MessageBox.Show(urls[m]);
}
webBrowser1.Navigate(new Uri(urls[0]));
webBrowser1.Dock = DockStyle.Fill;
webBrowser2.Navigate(new Uri(urls[1]));
webBrowser2.Dock = DockStyle.Fill;
webBrowser3.Navigate(new Uri(urls[2]));
webBrowser3.Dock = DockStyle.Fill;
webBrowser4.Navigate(new Uri(urls[3]));
webBrowser4.Dock = DockStyle.Fill;
}
connection.Close();
}
I can't understand this code:
for (int m = 0; m < 4 ; m++)
{
urls[m] = sumthisrow;
MessageBox.Show(urls[m]);
}
Why are you inserting in urls[m] the same value?
Bear in mind that in the previous loop the variable sumthisrow will keep only the last value just like:
sumthisrow = Reader.GetValue(Reader.FieldCount - 1).ToString();
EDIT: Also consider using a StringBuilder for creation of thisrow variable.
EDIT 2: Put your disposable objects into a using statement.