Below is my code. I'm trying to display some data as an array drawing from a SQL server. The problem is when I get to foreach I can't seem to get it to display the data correctly and it either keep repeating the data or just doesn't display it. I apologize if this questions seems basic I am a noob to programming and from what I have have researched I think I need to change my writeline to a write and potentially do another for loop....just not entirely sure any suggestions would help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
string connection = "Data Source=INIWS64-04;Initial Catalog=INEW18_2013;Network Library=DBMSSOCN; User ID=recordsadmin;Password=security";
DataTable table = new DataTable();
string Sql = "";
Sql = "select * from qryEDocRequest order by Request_ID";
using (SqlConnection conn = new SqlConnection(connection))
{
try
{
conn.Open();
SqlCommand comm = new SqlCommand(Sql, conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
{
adapter.Fill(table);
}
for (int i = 0; i < table.Rows.Count; ++i)
{
DataRow row = table.Rows[i];
for (int w = 0; w < table.Columns.Count; ++w)
{
StringBuilder array = new StringBuilder();
foreach (Char Item in row.ItemArray.ToString())
{
array.Append(Item + ",");
}
Console.WriteLine(array);
}
}
}
catch (Exception Test)
{
throw Test;
}
}
}
}
}
Here is a lot easier way to do what you are trying to do:
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
{
adapter.Fill(table);
}
foreach(var row in table.Rows)
{
Console.WriteLine(String.Join(",", row.ItemArray));
}
based off of your response I was able to resolve using the foreach as follows
{
adapter.Fill(table);
}
foreach (DataRow row in table.Rows)
{
Console.WriteLine(String.Join(",", row.ItemArray));
}
Thanks so much this was the simplest way
Related
I'm using an MDF database with the OpenFileDialog class to import a single CSV file to a database. That works fine for a single CSV file, but I need to open and process multiple CSV files in bulk.
How can I improve my code? I've tried using a for loop.
Here is my code to process a single CSV file:
ofd.Filter = "CSV files (*.csv) | *.csv; | CSV PRN files (*.prn,) |*.prn;";
ofd.FileName = "";
ofd.ShowDialog();
DataTable dt = new DataTable();
string line = null;
int i = 0;
using (StreamReader sr = File.OpenText(ofd.FileName))
{
while ((line = sr.ReadLine()) != null)
{
string[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
foreach (var item in data)
{
dt.Columns.Add(new DataColumn());
}
i++;
}
DataRow row = dt.NewRow();
row.ItemArray = data;
dt.Rows.Add(row);
}
}
}
string symbolName = dt.Rows[1][0].ToString();
string strConnection =
#"Data Source =.\SQLEXPRESS; AttachDbFilename = C:\USERS\JEF\DOCUMENTS\DATABASE1.MDF; Integrated Security = True; Connect Timeout = 30; User Instance = True";
SqlConnection condb2 = new SqlConnection(strConnection);
string createTablerow ="create table ["+symbolName+"] (code1 VARCHAR(100) COLLATE Arabic_CI_AI_KS_WS,date1 varchar(50),open1 varchar(50),high1 varchar(50),low1 varchar(50),close1 varchar(50),vol1 varchar(50))";
using (SqlConnection connection = new SqlConnection(strConnection))
{
SqlCommand command1 = new SqlCommand(createTablerow, connection);
connection.Open();
command1.ExecuteNonQuery();
}
using (SqlConnection cn = new SqlConnection(strConnection))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
copy.ColumnMappings.Add(0, "code1");
copy.ColumnMappings.Add(1, "date1");
copy.ColumnMappings.Add(2, "open1");
copy.ColumnMappings.Add(3, "high1");
copy.ColumnMappings.Add(4, "low1");
copy.ColumnMappings.Add(5, "close1");
copy.ColumnMappings.Add(6, "vol1");
copy.DestinationTableName = "[" + symbolName + "]";
copy.WriteToServer(dt);
}
}
I moved some of you code around to make it more efficient :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ofd.FileName = "";
ofd.ShowDialog();
string line = null;
int i = 0;
string strConnection =
#"Data Source =.\SQLEXPRESS; AttachDbFilename = C:\USERS\JEF\DOCUMENTS\DATABASE1.MDF; Integrated Security = True; Connect Timeout = 30; User Instance = True";
using (SqlConnection connection = new SqlConnection(strConnection))
{
connection.Open();
SqlBulkCopy copy = new SqlBulkCopy(connection);
copy.ColumnMappings.Add(0, "code1");
copy.ColumnMappings.Add(1, "date1");
copy.ColumnMappings.Add(2, "open1");
copy.ColumnMappings.Add(3, "high1");
copy.ColumnMappings.Add(4, "low1");
copy.ColumnMappings.Add(5, "close1");
copy.ColumnMappings.Add(6, "vol1");
foreach (string file in ofd.FileNames)
{
using (StreamReader sr = File.OpenText(file))
{
DataTable dt = new DataTable();
while ((line = sr.ReadLine()) != null)
{
string[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
foreach (var item in data)
{
dt.Columns.Add(new DataColumn());
}
i++;
}
DataRow row = dt.NewRow();
row.ItemArray = data;
dt.Rows.Add(row);
}
}
string symbolName = dt.Rows[1][0].ToString();
string createTable = string.Format("create table [{0}] (code1 VARCHAR(100) COLLATE Arabic_CI_AI_KS_WS,date1 varchar(50),open1 varchar(50),high1 varchar(50),low1 varchar(50),close1 varchar(50),vol1 varchar(50))",
symbolName);
using (SqlCommand command1 = new SqlCommand(createTable, connection))
{
command1.ExecuteNonQuery();
copy.DestinationTableName = "[" + symbolName + "]";
copy.WriteToServer(dt);
}
}
}
}
}
}
}
In order to process multiple files at once you will need to use a parallel code. Your use of "for" was a nice try, but "for" loops still run concurrently, which means one at a time.
The easiest way to achieve this parallel processing in this case would be to use Parallel.Foreach, here is a Microsoft guide about it: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-foreach-loop
I have a method in C# to execute a stored procedure. This will be called from a Script Component in SSIS 2014 (which also calls out to a web service for data). I'd like to be able to pass a dynamic list of SQL Parameters and Values. I was thinking about just using an array (string [,]), but in reality I think it's more of a key-value pair since I really only need 2 columns.
Is there a better/cleaner way to do this?
Here's what I have so far (semi-working .NET Fiddle example here):
using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;
public class Program
{
public static void Main()
{
// Code for getting data from web service goes here.
string[,] paramsArray = new string[,]
{
{"#ShipmentId", "123456"},
{"#TransDate", "2016-01-25"},
{"#FromLocation", "123"},
{"#ToLocation", "456"},
{"#Status", "Delivered"},
{"#TrackingNo", "1Z456789123"},
{"#UpdatedAtCarrier", DateTime.Now.ToString()},
};
SqlStoredProcedureParamArrayNoReturn("My Connection String", "My_Stored_Proc_To_Run", paramsArray);
}
public static void SqlStoredProcedureParamArrayNoReturn(string dbConnection, string procName, string[,] paramArray)
{
for (int r = 0; r < paramArray.GetLength(0); r++)
{
Console.WriteLine(paramArray[r,0] + " => " + paramArray[r,1]);
}
if (paramArray.GetLength(1) != 2)
{
Console.WriteLine("paramArray has too few/too many columns. Exiting method...");
System.Diagnostics.Debug.WriteLine("paramArray has too few/too many columns. Exiting method...");
}
using (SqlConnection conn = new SqlConnection(dbConnection))
{
SqlCommand cmd = new SqlCommand(procName, conn);
cmd.CommandType = CommandType.StoredProcedure;
for (int r = 0; r < paramArray.GetLength(0); r++)
{
cmd.Parameters.Add(new SqlParameter(paramArray[r, 0], paramArray[r, 1]));
}
cmd.Connection.Open();
cmd.ExecuteNonQuery();
System.Diagnostics.Debug.WriteLine("SQL Command executed successfully.");
}
}
}
I got the error message below when I tried to upload a csv file to a SQL Server table using C# (csv file has no header).
Error Message : "A column named ' ' already belongs to this DataTable"
I tried to find some solutions somewhere on the web but I'm really stuck with it.
My code :
SqlConnection con = new SqlConnection(#"server=.;Initial Catalog=myDtabase;Integrated Security=SSPI;");
string filepath = #"c:\\my_CSV_file.csv";
StreamReader sr = new StreamReader(filepath);
string line = sr.ReadLine();
string[] value = line.Split(',');
DataTable dt = new DataTable();
DataRow row;
foreach (string dc in value)
{
dt.Columns.Add(new DataColumn(dc));
}
while (!sr.EndOfStream)
{
value = sr.ReadLine().Split(',');
if (value.Length == dt.Columns.Count)
{
row = dt.NewRow();
row.ItemArray = value;
dt.Rows.Add(row);
}
}
SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
bc.DestinationTableName = "my_SQLServer_Table";
bc.BatchSize = dt.Rows.Count;
con.Open();
bc.WriteToServer(dt);
bc.Close();
con.Close();
I think this link will help you get this done.
http://forums.asp.net/t/1695615.aspx
As usual, there is more than one way to skin a cat. So, if yo don't like the solution listed above, try this script, which I know will work for you.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Configuration;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string server = "EXCEL-PC\\EXCELDEVELOPER";
string database = "AdventureWorksLT2012";
string SQLServerConnectionString = String.Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI", server, database);
string CSVpath = #"C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Bulk Copy from CSV to SQL Server Table\WindowsFormsApplication1\bin"; // CSV file Path
string CSVFileConnectionString = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};;Extended Properties=\"text;HDR=Yes;FMT=Delimited\";", CSVpath);
var AllFiles = new DirectoryInfo(CSVpath).GetFiles("*.CSV");
string File_Name = string.Empty;
foreach (var file in AllFiles)
{
try
{
DataTable dt = new DataTable();
using (OleDbConnection con = new OleDbConnection(CSVFileConnectionString))
{
con.Open();
var csvQuery = string.Format("select * from [{0}]", file.Name);
using (OleDbDataAdapter da = new OleDbDataAdapter(csvQuery, con))
{
da.Fill(dt);
}
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(SQLServerConnectionString))
{
bulkCopy.ColumnMappings.Add(0, "MyGroup");
bulkCopy.ColumnMappings.Add(1, "ID");
bulkCopy.ColumnMappings.Add(2, "Name");
bulkCopy.ColumnMappings.Add(3, "Address");
bulkCopy.ColumnMappings.Add(4, "Country");
bulkCopy.DestinationTableName = "AllEmployees";
bulkCopy.BatchSize = 0;
bulkCopy.WriteToServer(dt);
bulkCopy.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
}
}
The CsvHelper NuGet library has an implementation for IDataReader which you can pass into the BulkCopy WriteToServer method. This makes for really simple code and allows you to customize the data import.
using CsvHelper;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System.Globalization;
using System.IO;
public int ReplaceTableWithFile(string table, FileInfo csvFile)
{
using var fileReader = new StreamReader(csvFile.OpenRead());
using var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture);
using var csvDataReader = new CsvDataReader(csv);
var connection = GetDbConnection();
using var command = new SqlBulkCopy(connection);
command.EnableStreaming = true;
command.DestinationTableName = table;
command.WriteToServer(csvDataReader);
return command.RowsCopied;
}
CsvDataReader from CsvHelper NuGet package
I have the following code:
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeClock
{
class Company
{
DataTable rows = new DataTable();
public Company()
{
MySqlConnection connection = null;
try
{
string connectionString = TimeClock.Properties.Settings.Default.timeclockConnectionString;
connection = new MySqlConnection(connectionString);
connection.Open();
MySqlCommand command = new MySqlCommand("SELECT * FROM companies WHERE ID = #ID LIMIT 1", connection);
command.Parameters.AddWithValue("#ID", TimeClock.Properties.Settings.Default.CompanyID);
MySqlDataAdapter da = new MySqlDataAdapter(command);
da.Fill(rows);
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
Console.WriteLine(ex);
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}
public String getName()
{
DataRow row = rows.Rows[0];
return row["company_name"].ToString();
}
}
}
I know why I'm getting this error: say that no records were found in the database, the of course row[0] will no exist, hence the exception. But how do I deal with when there are no records to store in the Datatable? By the way, I'm quite new to C# and any input would be great; feel free to criticize.
Before you access a collection
DataRow row = rows.Rows[0];
you'll have to make sure that the item exists:
if(rows.Count > 0)
DataRow row = rows.Rows[0];
always
You must change getName function.
public String getName()
{
if (rows.Rows != null && rows.Rows.Count > 0)
{
DataRow row = rows.Rows[0];
return row["company_name"].ToString();
}
return string.Empty;
}
To read data from SQL I'm doing it like so:
using (SqlCommand SelectCommand = new SqlCommand(strbSelect.ToString()))
{
SelectCommand.Parameters.AddWithValue("Asset", AssetNumber);
SelectCommand.Parameters.AddWithValue("Subnumber", Subnumber);
SelectCommand.Connection = new SqlConnection(GetConnectionString());
SelectCommand.Connection.Open();
using (SqlDataReader Reader = SelectCommand.ExecuteReader())
{
if (Reader.HasRows)
{
while (Reader.Read())
{
if (Reader[0] != DBNull.Value)
{
ReturnValue = Reader.GetBoolean(0);
}
}
}
else
return false;
}
SelectCommand.Connection.Close();
}
StrbSelect is a StringBuilder.
I want to output my MySQL query to a li tag full of tables my select statement is working, I am just using the sample DB from MySQL world cities, my question is what is the simplest way to access individual rows and columns? Should I create a new Class or struct to push the data into? I want to be able to convert the data table into something like a List of HashTables? should I use something like JSON.net?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Data;
using Newtonsoft.Json;
namespace MySQL
{
public partial class _default : System.Web.UI.Page
{
string connStr = "server=localhost;User Id=root;Persist Security Info=True;database=world; Password=root";
MySqlDataAdapter countries;
DataSet ds;
protected void Page_Load(object sender, EventArgs e)
{
MySqlConnection conn = new MySqlConnection(connStr);
string sql = "SELECT * FROM country";
countries = new MySqlDataAdapter(sql, conn);
MySqlCommandBuilder cb = new MySqlCommandBuilder(countries);
ds = new DataSet();
countries.Fill(ds, "Country");
}
}
}
I am very well versed with jquery, javascript, angularjs, I am not concerned about the html output but I want to know whats the easiest way to access the individual columns? and rows to output them?
I think you want to access all tables by row and columns.
Do this
MySqlConnection conn = new MySqlConnection(connStr);
string sql = "SELECT * FROM country";
countries = new MySqlDataAdapter(sql, conn);
MySqlCommandBuilder cb = new MySqlCommandBuilder(countries);
ds = new DataSet();
countries.Fill(ds, "Country");
DataTable dt;
for (int i = 0; i <ds.Tables.Count; i++)//traverse by each table in dataset
{
dt = ds.Tables[i];
for (int j = 0; j < dt.Rows.Count; j++)//traverse by row
{
Response.Write("Current Row--> "+j.ToString()+Environment.NewLine);
object[] ob = dt.Rows[j].ItemArray; // get array of column from present row
for (int k = 0; k <= ob.GetUpperBound(0); k++)
{
Response.Write("Current column Number--> "+k.ToString()+" Value = "+ob[k].ToString()+Environment.NewLine);
}
}
}