Make Data columns from a sql adapter - c#

Is there a way, where I can use a sql adapter and convert the sql query results into a Data Columns? I'm kinda new a datatables. I need to build this dynamically since my column names are stored into a sql table. I keep running into datarows not columns. What I have built so far:
string feedcolumns = #"select FeedColumnName from myTable where FeedProcessID = #feedprocessid";
SqlCommand columnscommand = new SqlCommand(feedcolumns, connUpd);
DataTable dt = new DataTable("datafeed");
foreach(DataColumn dc in dt.Columns)
{
dc = new
dt.Columns.Add(dc);
}

You can fill a DataTable directly from an SqlReader, no need to go column by column.
One thing I did notice was that your SQL statement had a parameter in it that was never assigned to the command object, so I added it in
string feedcolumns = "select FeedColumnName from myTable where FeedProcessID = #feedprocessid";
DataTable dt = new DataTable("datafeed");
using (SqlConnection connUpd = new SqlConnection("MyConnection")) {
using (SqlCommand columnscommand = new SqlCommand(feedcolumns, connUpd)) {
columnscommand.Parameters.AddWithValue("#feedprocessid", feedprocessid);
connUpd.Open();
var dataReader = columnscommand.ExecuteReader();
dt.Load(dataReader);
}
}

Related

Join query in a SQL Server database and a DBF in C #

Can you help me with the following?
I have two databases: one in SQL Server making the connection with ADO.NET; the other is a DBF database which makes a class for the connection of the same. I want to make a comparison of data from one table to the other, since they have the same structure, and I want to see what data is missing from both the SQL Server and the DBF.
namespace log
{
static class Program
{
private static ECEntities1 dc = new ECEntities1();
public static void Main()
{
// Query in BDD SQL Server
var query =
from HInvoice in dc.HInvoice
where HInvoice.DOB == '2020-03-01'
select HInvoice.DOB
// Print data
foreach (var item in query)
{
Console.WriteLine(item);
}
// Query in BDD BDF
string path = AppDomain.CurrentDomain.BaseDirectory + #"db";
DataTable dt = DBF.ObtenerDatos(path, "GNDITEM.Dbf");
// Print Data
foreach (DataRow dtRow in dt.Rows)
{
// On all tables' columns
foreach (DataColumn dc in dt.Columns)
{
var field1 = dtRow[dc].ToString();
Console.WriteLine(field1);
}
}
}
}
}
I will answer myself, I am new so the question was how could I be focused, but that was not the way so I changed the focus what I did was the following:
I created a new project where I sent the DBF table to my SQL Server database through a stored procedure and from there make the comparison
Create the connection to the Dbf database.
OleDbConnection cnn = new OleDbConnection();
OleDbDataAdapter da = new OleDbDataAdapter();
OleDbCommand cmd;
string PathArchivo = (#"\\ruta_archivo");
string NombreArchivo = "GNDITEM.Dbf";
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + #PathArchivo + ";Extended Properties=dBASE IV;User ID=;Password=";
cmd = new OleDbCommand("select * from " + NombreArchivo, cnn);
da.SelectCommand = cmd;
cnn.Close();
var dt = new DataTable();
da.Fill(dt);
Pass the parameters to a DataTable
var dtParametro = new DataTable();
dtParametro.Columns.Add("parametro1", typeof(string));
dtParametro.Columns.Add("parametro2", typeof(string));
dtParametro.Columns.Add("parametro3", typeof(string));
dtParametro.Columns.Add("parametro4", typeof(string));
dtParametro.Rows.Add(drAdd);
// On all tables' columns
Then with a For we fill the DataTable with the information from the DBF table
foreach (DataRow dr in dt.Rows)
{
drAdd["TYPE"] = dr["parametro1"].ToString();
drAdd["EMPLOYEE"] = dr["parametro2"].ToString();
drAdd["CHECK"] = dr["parametro3"].ToString();
drAdd["ITEM"] = dr["parametro4"].ToString();
dtParametro.Rows.Add(drAdd);
}
Finally I connect to the SQL Server database and call the stored procedure
string cadena1 = #"conexionabdd...";
var cmda = new SqlCommand("Insertar_tbl_GNDITEM1", new SqlConnection(cadena));
cmda.CommandType = CommandType.StoredProcedure;
cmda.Parameters.Add("#param", SqlDbType.Structured).Value = dtParametro;
cmda.Connection.Open(); // abrimos la conexion
cmda.ExecuteNonQuery(); // lo ejecutamso
cmda.Connection.Close(); // cerramos la conexion
We review the database and see that the data is already in the same
PS: In addition to this, you must create the database in the SQL Server, also create a datatype for that table and the stored procedure, here is the video that will guide me, I hope it will be helpful for someone else Video

Windows Forms get data from database and display in label

I want to grab data from database and display in labels based on what the user selects in the list view.
I'm going off an example that does this with two list views, but I don't know how to do it when I'm sending data to a label.
This is the list view example I'm using (my label code is below this)
private void PopulateRecipeIngredients()
{
string query = "SELECT a.Name FROM Ingredient a " +
"INNER JOIN RecipeIngredient b ON a.Id = b.IngredientId " +
"WHERE b.RecipeId = #RecipeId";
// # is a parameter
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
// whatever recipe is selected in lstRecipes box, get the id of that and pass into query above
command.Parameters.AddWithValue("#RecipeId", lstRecipes.SelectedValue);
// DataTable holds the data return from query
DataTable ingredientTable = new DataTable();
// SqlDataAdapter object adapter fills the ingredientTable DataTable object with results from query
adapter.Fill(ingredientTable);
// Display value of Name ex. salad
lstIngredients.DisplayMember = "Name";
// Id column is how we reference
lstIngredients.ValueMember = "Id";
// connect list box on form to data in recipeTable
lstIngredients.DataSource = ingredientTable;
}
}
MY CODE:
private void PopulateCourseDetails()
{
string query = "SELECT * FROM Course_Info WHERE Id = #CourseId";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#CourseId", lstCourses.SelectedValue);
DataTable courseTable = new DataTable();
adapter.Fill(courseTable);
lblCourseId.Text = "Course_id";
lblCourseSection.Text = "Course_section";
lblCourseName.Text = "Course_name";
lblCourseDay.Text = "Course_day";
lblCourseStartTime.Text = "Course_start_time";
lblCourseEndTime.Text = "Course_end_time";
lblCourseProfessor.Text = "Course_professor";
lblCourseProfessorEmail.Text = "Course_professor_email";
lstCourses.ValueMember = "Id";
}
}
lblCourseId.Text = (string)courseTable.Rows[0]["Course_id"]
should work as long as you have one row in the result table
Assuming that your DataTable has now been properly populated, you now have a table with a number of rows.
First you need to pull out the first row
var row = courseTable.Rows.FirstOrDefault();
Now you've got a row with a number of columns. You can access each column by either index or column name.
lblCourseId.Text = row[0];
If you want the label to maintain it's header, you can do something like
lblCourseId.Text = "Course_id: " + row[0];

Iterate Multiple DataTables

I have a SQL Server stored procedure that I run two select statements. I can easily return one select statement and store it in a DataTable but how do I use two?
How can I set my variable countfromfirstselectstatement equal to the count returned from my first select statement and how can I set my variable countfromsecondselectstatement equal to the count returned from the second select.
private void ReturnTwoSelectStatements()
{
DataSet dt112 = new DataSet();
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("Return2SelectStatements", con))
{
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandType = CommandType.StoredProcedure;
da.Fill(dt112);
}
}
}
DataTable table1 = dt112.Tables[0];
DataTable table2 = dt112.Tables[1];
string countfromFirstSelectStatement = table1.Rows.Count().ToString();
string countfromSecondSelectStatement = table2.Rows.Count().ToString();
//I only want to iterate the data from the 1st select statement
foreach (DataRow row in dt112.Rows)
{
}
}
You could also directly use the DbDataReader (cmd.ExecuteReader()), which gives you NextResult to advance to the next result set. DataTable.Load allows you to load rows from the data reader to the table.
DbDataAdapter is really a bit of an overkill for just reading data into a data table. It's designed to allow the whole CRUD-breadth of operation for controls that are abstracted away from the real source of data, which isn't really your case.
Sample:
using (var reader = cmd.ExecuteReader())
{
dataTable1.Load(reader);
if (!reader.NextResult()) throw SomethingWhenTheresNoSecondResultSet();
dataTable2.Load(reader);
}
Fill a Dataset with both select statements and access it:
....
DataSet dataSet = new DataSet();
da.Fill(dataSet);
....
DataTable table1 = dataSet.Tables[0];
DataTable table2 = dataSet.Tables[1];
string countfromFirstSelectStatement = table1.Rows.Count.ToString();
string countfromSecondSelectStatement = table2.Rows.Count.ToString();

get data from variable table and return as datatable c#

I need to get retrive all of the data from specified tables and I don't need the data to be strongly typed so I am returning it as a data table.
public DataTable GetByTypeName(String t)
{
var type = Type.GetType(t);
var dt = new DataTable();
using (var sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["MasterPlanConnectionString"].ConnectionString))
{
var sqlComm = new SqlCommand("SELECT * FROM #table", sqlConn);
sqlComm.Parameters.AddWithValue("#table", type.Name);
sqlConn.Open();
var dr = sqlComm.ExecuteReader(CommandBehavior.CloseConnection);
dt.Load(dr);
}
return dt;
}
When I run this I get the error
System.Data.SqlClient.SqlException was unhandled by user code
Message=Must declare the table variable "#table".
I cannot figure out why this isn't working as I have declared #table. I know this method is open to some bad sql attacks so I plan to add in some protection about exactly what types can be queried against.
You can construct your query dynamically - (should be ok over here, but may expose your query to sql injection)
var query = String.Fromat("Select * from [{0}]", type.Name);
var sqlComm = new SqlCommand(query, sqlConn);
/*sqlComm.Parameters.AddWithValue("#table", type.Name);*/

fetch column names for specific table

I want to fetch all the column names for specific table..
I am using msaccess and C# .net 2008.
You can fetch schema information for a given query through OleDb using the SchemaOnly CommandBehavior and the GetSchemaTable method, as follows:
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var con = new OleDbConnection(conStr))
{
con.Open();
using (var cmd = new OleDbCommand("select * from Suppliers", con))
using (var reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
var table = reader.GetSchemaTable();
var nameCol = table.Columns["ColumnName"];
foreach (DataRow row in table.Rows)
{
Console.WriteLine(row[nameCol]);
}
}
}
A variant of bubi's method for a specific table:
public List<string> GetTableColumnNames(string tableName)
{
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var connection = new OleDbConnection(conStr))
{
connection.Open();
var schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Columns,
new Object[] { null, null, tableName });
if (schemaTable == null)
return null;
var columnOrdinalForName = schemaTable.Columns["COLUMN_NAME"].Ordinal;
return (from DataRow r in schemaTable.Rows select r.ItemArray[columnOrdinalForName].ToString()).ToList();
}
}
Of course first you might want to check if the table actually exists before getting its column names:
public bool TableExists(string tableName)
{
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var connection = new OleDbConnection(conStr))
{
connection.Open();
var tables = connection.GetSchema("Tables");
var tableExists = false;
for (var i = 0; i < tables.Rows.Count; i++)
{
tableExists = String.Equals(tables.Rows[i][2].ToString(),
tableName,
StringComparison.CurrentCultureIgnoreCase);
if (tableExists)
break;
}
return tableExists;
}
}
This retrieves all the columns of all tables and views
DataTable schemaTable = ((OleDbConnection)jetConnection).GetOleDbSchemaTable(
System.Data.OleDb.OleDbSchemaGuid.Columns,
new object[] { null, null, null, null });
I found this article while trying to build a C# application to migrate an Access database. The database I'm migrating is an Access 2007/2010 file with .accdb extension.
If you use this code on a table that has Memo or Attachment columns (available in accdb files), it will return the type of these columns as string (wchar).
I had trouble finding much information about how to deal with these types of columns, so I wanted to provide a link to the article that helped me figure out how to handle them:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d15606f9-f38d-4a1b-8ce3-000c558e79c5
I took the bottom example in that thread and converted it to C#. I did have to add this using statement to the module to avoid having to edit all of the references to "AccessDao":
using AccessDao = Microsoft.Office.Interop.Access.Dao;
My apologies for tacking onto an old thread, but I used this thread as a starting point for writing my code and didn't realize this gotcha right away.
Here's code to get the column names in the order they appear in the Access table. The examples in the other answers here return the column names in alphabetical order (at least for me... using the Microsoft Access Database Engine 2016 Redistributable and .NET Core 3.1).
Based on qnaninf's code example:
var schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName });
var columnOrdinalForName = schemaTable.Columns["COLUMN_NAME"].Ordinal;
var columnOrdinalForOrdinal = schemaTable.Columns["ORDINAL_POSITION"].Ordinal;
var rows = schemaTable.Rows;
var columns = from DataRow r in schemaTable.Rows
orderby r.ItemArray[columnOrdinalForOrdinal]
select new
{
Ordinal = r.ItemArray[columnOrdinalForOrdinal].ToString(),
ColumnName = r.ItemArray[columnOrdinalForName].ToString()
};
You can get the column names in Vb.net and Oledb from MS access database as follows.
'In Vb.net with OleDb
Dim adapter As new OleDb.OleDbDataAdapter
Dim ds As New DataSet
cmd.CommandText = "select * from table_name where 1=2"
adapter.SelectCommand = cmd
adapter.Fill(ds)
adapter.Dispose()
cmd.Dispose()
For Each dr In ds.Tables(0).Columns
ComboBox1.Items.Add(dr.ToString) 'The Column name will come in this combobox
Next

Categories

Resources