C# - Insert DataSet into a SQL Table - c#

I have a DataSet that I fill with values from a XML-file. I would like to insert the values then into a SQL table. How do I do that?
Here is how I fill my DataSet:
DataSet dataset = new DataSet();
dataset.ReadXml(xmlfile);
customer.DataSource = dataset.Tables[0];

If all you're ever going to do is inserts, then the simplest way is to just loop through the rows in the DataTable and create and execute a DbCommand for each row. The specific syntax to use depends on the kind of database you're using; for SQL Server, it might look like this:
string sql = "INSERT INTO T (A, B, C) VALUES (#A, #B, #C)";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
foreach (DataRow r in myTable.Rows)
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("#A", r["A"]);
cmd.Parameters.AddWithValue("#B", r["B"]);
cmd.Parameters.AddWithValue("#C", r["C"]);
cmd.ExecuteNonQuery();
}
}
This glosses over many, many possible complicating factors, e.g. exception handling, filtering out rows with the wrong DataRowState, calling AcceptChanges on the DataRow, updating identity columns with the value assigned by the database, and so on. There's a lot to understand in ADO.NET, and that stuff's in there for a reason. But if all you're going to do is insert rows, and the DataColumn objects in your DataTable have the right names and types and proper values for Size and AllowDbNull, and there are no foreign-key relations involved, and you're not going to encounter duplicate primary keys with existing data in the table, the above should work.

My suggestion would be to create a stored procedure for your insert and then create a method that traverses the data set, and sets the parameters of your stored proc and then executes it.

I think you would need to loop through the dataset and perform inserts.
You can obviously do this with a sproc, and you just pass along the parameters, or with LINQ.
Either way should work.

This completely depends on you existing Data access Layer.
If one doesn't exist i would look more towards LinqtoSQL rather than using Stored procedures, Stored procedures are more difficult to manage

Simple,
Just use the DataSet.ReadXml() method.
http://msdn.microsoft.com/en-us/library/system.data.dataset.readxml.aspx
Now if your xml is different from your schema, then your most likely going to have to loop and fill your schema specific dataset, then save as needed.

Related

How to execute a T-SQL script with temp tables and showing the table on C# MVC App

For example, I have a script that contains
insert into #temp from TABLES
insert into #temp1 from #temp
select * from #temp
I already have a C# MVC application. I just want to be able to execute the script above to display the #temp table on my front-end. I have seen the function ExecuteNonQuery(), however, it only shows the rows affected. Is there anyone that can point me a guide to solve this issue?
EDIT: I just want to run the script above and obtain the results, i don't want to rewrite the script in a framework.
Here is a sample for ExecuteNonQuery:
private void ExecuteNonQuery(string queryString, string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
From MSDN
And you can call your inserts like this: ExecuteNonQuery("insert into #temp from TABLES", connectionString);
For reading you can use ExecuteReader (MSDN) But if your table has many columns, this can be tedious to display all the columns. I prefer to use micro ORM (or data mapper otherwise) like Dapper - it is easy to use, minimum set up and with plenty of documentation.
Some people advise to use Entity Framework, but for this case it looks like will be an overkill. Also it has a steep learning curve.
If you want to read data from temporary table so use the ExecuteReader() and refer the following code.
using(SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var myString = rdr.GetString(0); //The 0 stands for "the 0'th column", so the
first column of the result.
// Do somthing with this rows string, for example to put them in to a list
listDeclaredElsewhere.Add(myString);
}
}
For select you have can use DataSet object and using DataAdapter fill data to DataSet
DataSet ds=new DataSet();
SqlDataAdapter da=new SqlDataAdapter(commandObject);
da.fill(ds);
DataSet ds=new DataSet();
SqlDataAdapter da=new SqlDataAdapter(commandObject);
da.fill(ds);
yes, that would work as well. but be aware that you are working with a DataSet (not DataTable on purpose?), and both DataSet and it's matching DataTable(s) are all dynamic objects without type safety (i.e. you are working with ds.Tables[0].Rows[0][2] as string; ).
good luck with the runtime exceptions.

Insert Records into SQL Server Database using C# Data Objects

I'm trying to properly bind a Data Adapter to my SQL database to insert records submitted by a person in a c# program. I feel like I am 80% of the way, but now i've hit a hitch.
So as in the code below, I can create and bind a Data Table just fine. I've tested the delete functions and they work just fine. I am now attempting to have a 'save' button insert a new row to my database. The problem I have now is that a user is supposed to put in their 'notes' and then hit save. I auto populate the rest of the columns, but I do not know how to grab the notes that the user entered.
Here is my code so far:
string userVerify = User.CurrentUser.UserName.ToString();
int participantID = this.mParticipant.ParticipantID;
DateTime date = DateTime.Now;
string properRow = dtNotes[1, dtNotes.NewRowIndex - 1].Value.ToString();
sqlDataAdapter.InsertCommand = new SqlCommand("INSERT INTO xxMyDatabasexx (ParticipantID,Verifier,Notes,Date) VALUES (#participantID,#notes, #userVerify,#date);");
sqlDataAdapter.InsertCommand.Parameters.AddWithValue("#participantID", participantID);
sqlDataAdapter.InsertCommand.Parameters.AddWithValue("#userVerify", userVerify);
sqlDataAdapter.InsertCommand.Parameters.AddWithValue("#date", date);
sqlDataAdapter.InsertCommand.Parameters.AddWithValue("#notes", properRow);
sqlDataAdapter.Fill(dataTable);
sqlDataAdapter.Update(dataTable);
I am aware that the properRow variable's logic is wrong. Of course if there are no rows then the program will crash, but also if no new note has been entered it will just reproduce the last note entered which of course is wrong as well. When i look into my dataTable at the time of sqlDataAdapter.Fill, I can see the note in the correct column but I don't know how to simply save it.
Any help is appreciated. Thanks.
EDIT:
What I was unaware of is that the InsertCommand (naturally) also needs the ExecuteNonQuery command with it. I was under the assumption that since both Delete and Update did not, that Insert wouldn't either. This seemed to fix the issue. Thanks all for the help.
You can insert the record into SQL Database without need for DataAdapter just by using Command object as shown in the following code snippet (just pass your Insert SQL statement string):
void SqlExecuteCommand(string InsertSQL)
{
try
{
using (SqlConnection _connSqlCe = new SqlConnection("Conn String to SQL DB"))
{
_connSql.Open();
using (SqlCommand _commandSqlCe = new SqlCommand(CommandSQL, _connSql))
{
_commandSql.CommandType = CommandType.Text;
_commandSql.ExecuteNonQuery();
}
}
}
catch { throw; }
}
The general format of SQL INSERT query string is shown below:
INSERT INTO YourTable (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
You can further extend this solution by adding parameters to the SQL String/Command in order to protect against possibility of SQL injection (see the following example):
INSERT INTO YourTable (column1,column2,column3,...)
VALUES (#param1,#param2,#param3,...);
_commandSql.Parameters.Add("#param1","abc");
_commandSql.Parameters.Add("#param2","def");
_commandSql.Parameters.Add("#param3","ghijklm");
You can also use the alternative syntax for SQL Parameters, like for e.g.:
_commandSql.Parameters.Add("#param1", SqlDbType.NChar).Value = "abc";
_commandSql.Parameters.Add("#param2", SqlDbType.NChar).Value = "def";
_commandSql.Parameters.Add("#param3", SqlDbType.NVarChar).Value = "ghijklm";
Pertinent to your particular question, it should be like:
"INSERT INTO xxMyDatabasexx (ParticipantID, Verifier, Notes, [Date]) VALUES (#participantID, #userVerify, #notes, #dt)"
_commandSql.Parameters.Add("#ParticipantID",SqlDbType.NChar).Value= participantID;
_commandSql.Parameters.Add("#userVerify",SqlDbType.NChar).Value= userVerify ;
_commandSql.Parameters.Add("#notes",SqlDbType.NVChar).Value= properRow ;
_commandSql.Parameters.Add("#dt",SqlDbType.DateTime).Value= DateTime.Now;
Note: in case ParticipantID is the IDENTITY (i.e. Autonumber) Column, then do not include it in INSERT statement.
Hope this may help.
It seems to me that You are a bit lost. The way adapters are meant to work is
fill table from database via adapter (or take empty table)
bind table to GUI or manually transfer the information to GUI
change/add/delete data in table via binding or manually
update changes (inserts/updates/deletes) into database via adapter
The changes in table are automatically traced, so the adapter knows, what should be updated/inserted/deleted and use appropriate commands.
If You use adapter just as a holder for command You can ExecuteNonQuery with arbitrary parameters, You pass the whole concept and do not need adapter at all (see #AlexBells answer).
Apart from this, are You really going to write all that plumbing code by hand? Life is too short. If I were You, I would look for some ORM. You get simple CRUDs or concurrency checking with no effort.

What is an efficient concise way to check if values in column of DataTable are contained in SQL query results?

I am converting data from a CSV file into a database. I put the data from the CSV file into a DataTable and am trying to validate the data.
One thing I want to check is that all of the values in a certain column of the DataTable (let's call it PersonID) are found in the columns of a table in the database I'm converting to (let's call that PeopleID).
So, I want to check if all of the values of PersonID are listed in the PeopleId table.
I have the results of the DataTable as follows:
var listOfPersonIdsInData = arguments.DataTable.Select("PersonId");
And I query the database to get the values of the PeopleId column:
var listOfPeopleIdsInDatabase = checkQuery.Execute<DataColumn>(#"SELECT DISTINCT PeopleId FROM People");`
What would be the best way to go about checking this in C#? I realize it's a somewhat basic question but the way I'm thinking of doing it is using two arrays. Read in the results of each into an array, then cycle through each value of array 1 to check if it's in array 2.
I feel like I'm re-inventing the wheel. I would really like to know a better way if there is one. If anyone could provide any advice I'd greatly appreciate it.
If you're using SQL 2008 I would recommend that you just pass the DataTable as parameter as a Table-Valued Parameter to a stored procedure or a Parameterized query and then use an Anti Join or Not In or Not Exists to determine if there are any rows in the DataTable that aren't in the SQL Table.
e.g.
Create the type
CREATE TYPE dbo.PersonTable AS TABLE
( PersonId int )
Then the proc
CREATE PROCEDURE usp_ValidateDataTable
(#CheckTable dbo.PersonTable READONLY) as
BEGIN
SELECT c.PersonID
FROM
#CheckTable c
WHERE
c.Person NOT IN (SELECT PersonID from dbo.People)
END
C# Code
SP Call
SqlCommand cmd= new SqlCommand("usp_ValidateDataTable" , cnn);
SqlParameter tvpParam = cmd.Parameters.AddWithValue("#CheckTable", listOfPersonIdsInData );
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.PersonTable";
SqlDataReader rdr = cmd.ExcuteReader();
C# Code
Parameterized Query Call
string query = #" SELECT c.PersonID
FROM #CheckTable c
WHERE c.Person NOT IN (SELECT PersonID from dbo.People)";
SqlCommand cmd= new SqlCommand(query , cnn);
SqlParameter tvpParam = cmd.Parameters.AddWithValue("#CheckTable", listOfPersonIdsInData );
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.PersonTable";
SqlDataReader rdr = cmd.ExcuteReader();
I have had to migrate much information and so far I think the best is:
Create a flat table with the information from the CSV and load all the data there
Create in the same SQL methods to extract standardized information
Construct a method in the same SQL crossing normalized information with the raw data
is really fast especially when the number of records is quite large (greater than 1M), plus you avoid the problem of optimizing your RAM management script/program. also load CSV to MySQL data is really easy check this
a tip: parameterized method for import and verify with an offset and limit value

How do I create a new VFP (OLEDB) table from an existing one using .NET?

We have an application that creates a number of Visual Foxpro (DBF) tables. Each of those tables have a different schema, but they all contain a known date field.
I've been asked to create another application (in C#) that will copy the last week's worth of data from each table to a new table (in a different folder to the source tables). The distinct tables will remain (e.g. if there are three source tables, there will be three destination tables).
Over time the tables may change (e.g. new fields added), so I can't make assumptions about table structure (apart from the existence of the aforementioned date field).
What's the easiest/best way to take the data from one table and create a new table with the same structure?
I know how to query the tables to extract the data (e.g. fill a DataSet with the last week's records). However, I'm thinking there must be a better way of creating a new table and filling it with the results than manually parsing all the field information in the schema and using that to recreate the the destination table.
Working with FoxPro seems to be different enough from SQL Server to give me a headache at each turn, so I need some guidance on my approach.
The production machine has the VFP 9 OLEDB driver installed on it. If possible, we'd prefer not to have to install much else.
To get an exact copy of the data, table, and records, you can do via a single SQL-Select via
OleDbConnection oConn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=C:\\SomePath");
OleDbCommand oCmd = new OleDbCommand();
oCmd.Connection = oConn;
oCmd.Connection.Open();
oCmd.CommandText = "select * from SomeTable where someCondition into table YourNewTable";
oCmd.ExecuteNonQuery();
oConn.Close();
Your where clause could be almost anything, and the Into TABLE clause tells the VFP engine to create the result set AS A NEW TABLE, so no need to explicitly declare types, columns, etc, query data from one and push into another...
One issue of consideration... Verify the user access to obviously be able to create, read, write wherever you are trying to create the new table. You can even specify a fully qualified path, such as C:\SomeOtherPath\Monthly\MyTable1 if need be...
Try something like this (note written in VB.NET and converted use www.developerfusion.co.uk/tools ):
using System.Data.OleDb;
using System.IO;
static class Module1
{
public static void Main()
{
OleDbConnection oConn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=C:\\");
OleDbCommand oCmd = new OleDbCommand();
{
oCmd.Connection = oConn;
oCmd.Connection.Open();
// Create a sample FoxPro table
oCmd.CommandText = "CREATE TABLE Table1 (FldOne c(10))";
oCmd.CommandType = CommandType.Text;
oCmd.ExecuteNonQuery();
}
oConn.Close();
oConn.Dispose();
oCmd.Dispose();
}
}
You can simply do a:
select * from myTable into table newTable [database dbName]
as DRapp showed. However you may want to get indexes as well (if any) (BTW creating indexes via VFPOLEDB is not supported directly but you can do so using ExecScript() function). Then the easiest would be to copy the table's DBF, CDX (and FPT) files. VFP is file based.

C# OLE DB: How can I reorder columns of database table by using a dataset?

I know this might be a bit awkward but I am trying to modify the order of certain columns in a MS Access database in C# with OLE DB. How can I commit a certain change in the order of the columns of a datatable in a dataset? If that is not possible, how can I reorder columns of database table by using a dataset?
Here is a sample of what I have (in C#):
command.Connection = conn;
command.CommandText = tableName;
command.CommandType = CommandType.TableDirect;
adapter = new OleDbDataAdapter(command);
dataset = new DataSet(tableName);
adapter.Fill(dataset, tableName);
dataset.Tables[0].Columns[dataset.Tables[0].Columns.Count-1].SetOrdinal(CB_PositionCol.SelectedIndex);
dataset.Tables[0].AcceptChanges();
The AcceptChanges does not seem to work for what I wish to do since I believe it only commits changes in DataRows...
Thank you for any help!
Use an ALTER TABLE statement with an OleDbCommand. DataSet, DataTable and DataTableAdapters are meant to be transparent to the underlying structure of the data. You can actually use Table Adapters to transform data from two different structures.
http://www.functionx.com/vbnet/oledb/Lesson02.htm

Categories

Resources