I am using C# to read a SQL stored procedure, put the results of the stored procedure into a C# data table and then reading the data table row by row to build up my "Insert into....values "etc. This creates my Excel spreadsheet with the correct data. However, instead of inserting row by row, is there a way of doing a bulk insert?
Failing that I was thinking of getting the stored procedure to write the results to a permanent table and therefore is there a way of doing an "Insert into ....select from ". When I have tried this in C# the code is unable to find the SQL table name specified "Microsoft database access engine cannot find the object ", what is the correct syntax and where do you specify where/how to access the SQL table?
Thanks
Hi, that link looks like it's using Microsoft.Office.Interop.Excel;
I'm using OLEDB (which i'm now beginning to regret!). So basically i have a C# class that is called from another component. This C# class reads a sql stored procedure, puts the results into a data table. I then set up the table definition using the OLEDBcommand "Insert into ( []) values ("?"). I then define the parameters e.g. cmd.Parameters.Add(columnHeading, OleDbType.VarChar, size) etc. Then for each row i find in the data table i set the cmd.Parameters[i].value = row[i], where parameters[i] is incremented for each column in that row. I then loop round for each data row and set cmd.Parameters[i].value appropriately. As I have to set the cmd.Parameters[i].Value for each row i find in my dataset and then cmd.ExecuteNonQuery();
, this is quite time consuming. So is there a way to bulk insert the data from the data table into the OLEDB command, if not, can i insert the data by referencing a SQL table directly and doing a "insert into..select from"?
You can separate your insert statements with a semicolon and run just 1 command. For instance ...
string sql = "insert into table (col1,col2) values ('row1','row1');"
sql += "insert into table (col1,col2) values ('row2','row2');"
sql += "insert into table (col1,col2) values ('row3','row3');"
SqlConnection conn = new SqlConnection("some connection string");
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
conn.ExecuteNonQuery();
conn.Dispose();
cmd.Dispose();
Or something similar. You are executing all 3 queries with 1 command. This might not work with databases other than SQL Server, but will definitely work with SQL Server.
Related
I have developed a web application to import Excel data into a SQL Server table using bulk copy column mapping. I used a select * from sheet query to copy the sheet data and insert into data table before writing it to table.
There are 20 columns in the sheet. The last column contains data of type datetime, string, integers and special characters. Its a mixed data type. When the application tried to copy and insert data into data table means it shows
Not a legal ole auth date
I have checked the last column values. Date value is correct only but it shows not a legal ole auth date issue.
Instead of using select * from sheet, is there any alternative approach like insert data into data table from Excel by row wise using for loop ?
Code is
OleDbConnection excelConnection1 = new OleDbConnection(excelConnectionString);
string query = string.Format("Select * from [{0}]", excelSheets[0]);
using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, excelConnection1))
{
dataAdapter.Fill(dt); **// issue raise when it try to fill the datatable**
}
I've successfully imported a tab-delimited file into a dataset in asp.net (C#). I can bind the dataset to a gridview, and see my data (that part works fine).
Now I want to insert that dataset table (the only table in the dataset) into a sql table using an INSERT command - I don't know enough about datasets to figure it out.
Actually you won't use the INSERT command, to insert a new table you're going to need this query:
string query = "CREATE TABLE myTable (column1 INT, column2 NVARCHAR(10))";
Source: Creating Databases and tables using c#
Where 'column1' is your column's name and INT the type. You can see more about the types here: http://www.w3schools.com/sql/sql_datatypes_general.asp
and you can also see more SQL commands here: http://www.w3schools.com/sql/sql_syntax.asp
I Try to insert to MySQL database in C#, but what i got is this error
"You have an error in your SQL syntax; check the manual that
corresponds to your Mysql server version for the right syntax to use
near "insert (NoNota, Nama, Tanggal, Tipe, Keterangan) VALUES ('1111',
'Kickass', '201" at line 1
i think the problem is the DateTime, in my database datatype i set it to DATETIME, Here is my code
string sqlQuery;
sqlQuery = "INSERT INTO insert (id, Name, Date, Type, Notes) VALUES ('1111', 'Kickass', '2013-09-09', 'Cash', 'Nothing')";
if (this.OpenConnection() == true)
{
cmd = new MySqlCommand(sqlQuery, connect);
cmd.ExecuteNonQuery();
CloseConnection();
MessageBox.Show("Operation INSERT is SUCCESS!!");
}
What's wrong with it? i try excute my SQL Queries it work very FINE in MySQL Workbench, it automatically convert the DateTime and insert it into the table. Any clue?
insert is a reserved word (INSERT INTO insert). Rename the table or escape with backticks. I'd highly recommend renaming.
You need to escape reserved words in MySQL like INSERT with backticks
INSERT INTO `insert` (id, Name, ...
^------^---------------------here
But it would be way better to rename your table. insert does not say anything about your data. Try to think of its content. When you have hundreds of tables in a database you need to name every one very carefully to keep track what it contains.
When you name your column, name it after the single word that finishes this sentance:
The data of my table holds ...
I am trying to store rows in a SQL Server 2008 table for a junkyard about documentation in all vehicles; I will run this program once a month that I receive a list with information for all vehicles. I know I can write a text file and do a "bulk insert" from a file.
However, I just wondered if there is a way to insert information stored in string arrays directly into SQL Server.
Right now I am doing a for loop and running 500 query commands to insert them, and for 500 records it only takes about 4 seconds the whole process.
I would like to know if there is a better way to insert the information from arrays directly without using a for-loop 500 times?
The code below works perfectly fine for me, however I would not like to use that kind of spaghetti code if there exists a better way to do it. Thanks in advance!
for (int i = 0; i < 500; i++)
{
con.Open();
SqlCommand myCommand = new SqlCommand("INSERT INTO [TESTCATALOG].[dbo].[TITLES] VALUES ('" + TitleNum[i] + "','" + VIN[i] + "','" + DateIssued[i] + "')", con);
myCommand.ExecuteReader();
con.Close();
}
You can use table valued parameters (TVP) to insert lists directly through a stored procedure.
Table-valued parameters are a new parameter type in SQL Server 2008. Table-valued parameters are declared by using user-defined table types. You can use table-valued parameters to send multiple rows of data to a Transact-SQL statement or a routine, such as a stored procedure or function, without creating a temporary table or many parameters.
This will also avoid the SQL Injection vulnerability currently present in your code.
See Table-Valued Parameters in SQL Server 2008 (ADO.NET) on MSDN to see how to call a stored procedure with a TVP with C#:
SqlCommand insertCommand = new SqlCommand(sqlInsert, connection);
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
"#tvpNewCategories",
addedCategories);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.CategoryTableType";
Yes, you can use linq to sql or linq to entities to achieve this in a single transaction.
You could use the SqlBulkCopy class. The SqlBulkCopy class requires your data be available as DataRow[], DataTable or `IDataReader.
From SQL Server 2008 onwards, you can use a table valued variable.
See "Passing a Table-Valued Parameter to a Parameterized SQL Statement" in MSDN.
you can use dataadapter for insert or update.
first add rows in a datatable in yor for loop then call dataadapter.update with datatable
How do I call stored procedures in bulk? I would like to do something like a bulk copy.
All that the stored procedure does is 8 selects for unique constraint and 8 inserts. With no returning value.
You cannot do that.
Bulk copy is a firehose dump of data into a table, you cannot call sprocs or anything else instead of just dumping it into an existing table.
What you can do, however, is dump the data using bulk copy into a temporary table with the right structure, and then afterwards call your sproc that moves that data into the real tables, possibly by modifying existing data instead of inserting it, or whatnot.
If you are using SQL Server 2008, then Table-Valued Parameters is a viable option.
First, you create a user-defined table type containing all of your expected columns and data types on the SQL Server side:
create type dbo.MyTableType as table
(
foo int,
bar varchar(100)
);
then use the above as the table type parameter for your stored procedure:
create procedure uspInsertMyBulkData
(
#myTable dbo.MyTableType readonly
)
as
/* now in here you can use the multi-row data from the passed-in table
parameter, #myTable, to do your selects and inserts*/
Then, on the C#/.NET client side, call this stored procedure via ADO.NET and pass in either a DataTable, an object that inherits from DbDataReader (such as DataTableReader), or an object of type IEnumerable<SqlDataRecord>:
// create my source DataTable
object [] row1 = {1, "a"};
object [] row2 = {2, "b"};
var myDataTable = new DataTable();
myDataTable.Columns.Add(new DataColumn("foo"));
myDataTable.Columns.Add(new DataColumn("bar"));
myDataTable.LoadDataRow(row1, true);
myDataTable.LoadDataRow(row2, true);
// bulk send data to database
var conn = new SqlConnection(connectionString);
var cmd = new SqlCommand("uspInsertMyBulkData", conn)
{
CommandType = CommandType.StoredProcedure
};
SqlParameter param = cmd.Parameters.AddWithValue("#myTable", myDataTable);
param.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();
If you want to bulk load data into a table (inserts), the SqlBulkCopy class is the way to go.
Alternatively, you can use the SqlDataAdapter. Set the InsertCommand to the stored procedure that will perform an insert, and map the datatable fields to the sproc parameters. If you have updated records in the datatable, you can also specify an UpdateCommand which will be fired for each updated row. Then call the Update method on the SqlDataAdapter passing it the datatable. You can set the UpdateBatchSize property to define how many records to send to the db in each roundtrip.
SqlServer stored procedures can accept xml, so you could prepare your bulk data as an xml file and pass it to a special-purpose stored procedure which would then call your original stored procedure for each row. You'd need the OPENXML function.
I hesitate to recommend the xml features of SqlServer, but this may be a case where they are appropriate.
I'm not saying that I recommend it, but you could put an insert trigger on the table you are bulk copying into that inserts into those 8 separate tables instead of the original one. You may need to have a tempdb big enough to store all the data though...
CREATE TRIGGER TRG_REPLACETRIGGER
ON BULK_TABLE
INSTEAD OF INSERT
AS BEGIN
INSERT TABLE1 (ID, VALUE) SELECT ID, VALUE1 FROM INSERTED
INSERT TABLE2 (ID, VALUE) SELECT ID, VALUE2 FROM INSERTED
-- ... TABLE3-7
INSERT TABLE8 (ID, VALUE) SELECT ID, VALUE8 FROM INSERTED
END