Updating SQL Server database with SqlDataAdapter - c#

I have a DataTable with new entries, and I want to add these to an existing database.
So I create a SqlDataAdapter and fill a second table with it, then I merge the two tables, and update the database, but nothing happens, the return value is 0, the database stays the same.
Here's my code:
DBManager.DBDestinationConnect(textBox10.Text, textBox9.Text, textBox8.Text, textBox7.Text, ref destinationConnection);
//DBManager is a Class, to connect with the database
CategoryAdapterBackup = new SqlDataAdapter("SELECT*FROM " + tablename, destinationConnection);
CategoryTableBackup = new DataTable();
CategoryAdapterBackup.Fill(CategoryTableBackup);
CategoryTableBackup.Merge(SubTable);
//SubTable is the DataTable with the new entries
CategoryAdapterBackup.Update(CategoryTableBackup);

I'm having a problem discerning your intentions with this code. Why not simply use sqlbulkcopy on SubTable? That would append the contents of SubTable to the destination SQL table. If you are afraid of duplicates, then insert the contents of SubTable Table to a Temp in the DB and maybe use a Join to insert rows into the destination table where not exists row in destination table.

Try with CategoryAdapterBackup.Flush() or with DBManager.Flush()
also, could be a good idea replace SELECT*FROM by SELECT * FROM (with spaces)

Related

Displaying last record after insertion c#

I read upon a document on how to retrieve the last record after inserted. However when I do, nothing gets filled on the datagridview. This is what I have.
static String connectionString = #"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename= C:\Users\home\Documents\C# Programs\program\Database.mdf ;Integrated Security = True";
private void displayLastInsertedRecord()
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select ##identity", connectionString))
{
DataTable table = new DataTable(connectionString);
dataAdapter.Fill(table);
employeeDataGridView.DataSource = table;
}
}
I checked to see if in fact the data is being stored into the database table and it actually is. It just not display factors such as their name, city, address, etc etc.Cannot figure out what I am doing incorrectly.
Your query is returning a single row, single column table, which contains the Primary Key value of the last inserted data row, in any table in your database, provided that such primary key is an IDENTITY column. Since you want the actual data, change your query from:
SELECT ##IDENTITY
to:
SELECT #LastID = ##IDENTITY; SELECT * FROM [YourTableName] WHERE [YourPrimaryKeyColumn] = #LastID
where [YourTableName] is the table you're interested in getting the inserted row from (must match last insert command, otherwise the returned dataset will either contain no rows, or have an accidentally matching record - basically, garbage data), and [YourPrimaryKeyColumn] is the name of the primary key column in the aforementioned table.
Also, consider using SCOPE_IDENTITY or IDENT_CURRENT instead.

C#: DataTable getting only one row of the search result

I'm having a sudden and strange problem with DataTable. I'm using C# with MySQL database to develop a system, and I'm trying to export custom reports. The problem is that, somehow, my DataTable is getting only one result (I've tested my query on MySQL and should be something like 30 results on the xls file and the DataTable).
Strangely, these functions are used in other parts of the system to export other kinds of reports, and work perfectly. This is the select function that I'm using:
public DataTable selectBD(String tabela, String colunas) {
var query = "SELECT " + colunas + " FROM " + tabela;
var dt = new DataTable();
Console.WriteLine("\n\n" + query + "\n\n");
try
{
using (var command = new MySqlCommand(query, bdConn)) {
MySqlDataReader reader = command.ExecuteReader();
dt.Load(reader);
reader.Close();
}
}
catch (MySqlException) {
return null;
}
bdConn.Close();
return dt;
}
And this is my query:
SELECT
cpf_cnpj, nomeCliente, agenciaContrato, contaContrato,
regionalContrato, carteiraContrato, contratoContrato,
gcpjContrato, avalistaContrato, enderecoContrato,
telefoneContrato, dataChegadaContrato, dataFatoGerContrato,
dataPrimeiraParcelaContrato, dataEmissaoContrato, valorPlanilhaDebitoContrato
FROM
precadastro
INNER JOIN
contrato
ON precadastro.cpf_cnpj = contrato.FK_cpf_cnpj
LEFT JOIN faseprocessual
ON contrato.idContrato = faseprocessual.FK_idContrato
And that is the result of the query on SQLyog
I've tested and the DataTable returned by the function only receive the one row, and it's not the first row of the MySQL results. Someone had this kind of problem before?
DataTable load expects primary key from your data (supplied by DataReader) and tries to guess it from passed rows. Since there's no such key, Load method guesses it's the first column (cpf_cnpj). But, values in that column aren't unique so the each row gets overwritten by next one, and the result is just one row in your DataTable.
It's the issue that persist for years, and I'm not sure there's one solution to rule them all. :)
You can try:
change query so that some unique values get into first column (unfortunately, I can't see something unique in your screenshot) or concatenate two or more values to get unique value.
Prepare DataTable by yourself by creating columns (this mirroring structure of resultset) and then iterate through DataReader to copy data.
add some autoincrement value in your query (or make temporary table with auto_increment column then fill that table)
Last suggestion could be something like this (I haven't worked much with mySql, so this is some suggestion i have googled :)):
SELECT
#i:=#i+1 AS id,
cpf_cnpj, nomeCliente, agenciaContrato, contaContrato,
regionalContrato, carteiraContrato, contratoContrato,
gcpjContrato, avalistaContrato, enderecoContrato,
telefoneContrato, dataChegadaContrato, dataFatoGerContrato,
dataPrimeiraParcelaContrato, dataEmissaoContrato, valorPlanilhaDebitoContrato
FROM
precadastro
INNER JOIN
contrato
ON precadastro.cpf_cnpj = contrato.FK_cpf_cnpj
LEFT JOIN faseprocessual
ON contrato.idContrato = faseprocessual.FK_idContrato
CROSS JOIN (SELECT #i:= 0) AS i
here's answer on SO which uses auto number in query.

Table schema as DataTable?

I did a search and found some seemingly related answers, but they don't really do what I'm after.
Given a valid connection string and a table name, I want to get a DataTable of the table. I.e. if the table has a column called "Name", I want the DataTable set up so I can do dt["Name"] = "blah";
The trick is, I don't want to hard code any of that stuff, I want to do it dynamically.
People tell you to use SqlConnection.GetSchema, but that gives you back a table with a bunch of stuff in it.
Everybody has random tricks like TOP 0 * from the table and get the schema from there, etc.
But is there a way to get the table with the primary keys, unique indexes, etc. Ie.. in the final format to do a bulk insert.
You can use SqlDataAdapter.FillSchema:
var connection = #"Your connection string";
var command = "SELECT * FROM Table1";
var dataAdapter = new System.Data.SqlClient.SqlDataAdapter(command, connection);
var dataTable = new DataTable();
dataAdapter.FillSchema(dataTable, SchemaType.Mapped);
This way you will have an empty DataTable with columns and keys defined and ready to use in code like dataTable["Name"] = "blah";.

Updating using DataTable in database table?

I have a table which has some 100-200 records.
I have fetch those records into a dataset.
Now i am looping through all the records using foreach
dataset.Tables[0].AsEnumerable()
I want to update a column for each record in the loop. How can i do this. Using the same dataset.
I'm Assumng your using a Data Adapter to Fill the Data Set, with a Select Command?
To edit the data in your Data Table and save changes back to your database you will require an Update Command for you Data Adapter. Something like this :-
SQLConnection connector = new SQLConnection(#"Your connection string");
SQLAdaptor Adaptor = new SQLAdaptor();
Updatecmd = new sqlDbCommand("UPDATE YOURTABLE SET FIELD1= #FIELD1, FIELD2= #FIELD2 WHERE ID = #ID", connector);
You will also need to Add Parameters for the fields :-
Updatecmd.Parameters.Add("#FIELD1", SQLDbType.VarCHar, 8, "FIELD1");
Updatecmd.Parameters.Add("#FIELD2", SQLDbType.VarCHar, 8, "FIELD2");
var param = Updatecmd.Parameters.Add("#ID", SqlDbType.Interger, 6, "ID");
param.SourceVersion = DataRowVersion.Original;
Once you have created an Update Command with the correct SQL statement, and added the parameters, you need to assign this as the Insert Command for you Data Adapter :-
Adaptor.UpdateCommand = Updatecmd;
You will need to read up on doing this yourself, go through some examples, this is a rough guide.
The next step is to Enumerate through your data table, you dont need LINQ, you can do this :-
foreach(DataRow row in Dataset.Tables[0].Rows)
{
row["YourColumn"] = YOURVALUE;
}
One this is finished, you need to call the Update() method of yout Data Adapter like so :-
DataAdapter.Update(dataset.Tables[0]);
What happens here, is the Data Adapter calls the Update command and saves the changes back to the database.
Please Note, If wish to ADD new rows to the Database, you will require am INSERT Command for the Data Adapter.
This is very roughly coded out, from the top of my head, so the syntax may be slightly out. But will hopefully help.
You should use original DataAdapter (adapter in code below) that was used to fill DataSet and call Update method, you will need CommandBuilder also, it depends what DB you are using, here is the example for SQL server :
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(dataset);
dataset.AcceptChanges();
Here is the good example :
http://support.microsoft.com/kb/307587
The steps would be something like:
- create a new DataColumn[^]
- add it to the data table's Columns[^] collection
- Create a DataRow [^] for example using NewRow[^]
- Modify the values of the row as per needed using Item[^] indexer
- add the row to Rows[^] collection
- after succesful modifications AcceptChanges[^]
Like this:
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("ProductName");
table.Rows.Add(1, "Chai");
table.Rows.Add(2, "Queso Cabrales");
table.Rows.Add(3, "Tofu");
EnumerableRowCollection<DataRow> Rows = table.AsEnumerable();
foreach (DataRow Row in Rows)
Row["ID"] = (int)Row["ID"] * 2;
Add the column like below.
dataset.Tables[0].Columns.Add(new DataColumn ("columnname"));
Update the columns values like below.
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
dataset.Tables[0].Rows[i]["columnname"] = "new value here";
}
Update Database
dataset.AcceptChanges();

Copy from dataset to access table in C#?

I have a dataset (from an XML file), I want to read the schema and values from this dataset and copy it into an access table.
I want to create the access database on fly (can use ADOX), create an access table (from ADOX) create the schema in this table and copy the values from dataset into this table.
I am getting an error when i try to create the table and add columns in it, Below is the code snippet which is giving me an error
DataSet ds = new DataSet();
Console.Write("The NAME IS" + FileName.Text.ToString());
ds.ReadXml("FILE_PATH" + FileName.Text.ToString());
ADOX.Catalog cat = new Catalog();
cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='DATABASE_NAME';Jet OLEDB:Engine Type=5");
Table tab = new Table();
tab.Columns.Append("Column Name", DataTypeEnum.adVarChar, 50);
// I am inserting 32 more columns in this manner
cat.Tables.Append(tab);
When I run this code block I get COM Exception : "TableID is invalid".
Am I trying to do this with a right approach? How can I copy the values from dataset to this table?
Could you try to assign a name to the table?
tab.TableName = "MyName";

Categories

Resources