I'm trying to replace the table in Excel 2007 using OLEDB.
Firstly I'm executing the command "Drop Table", than "Create Table" and it works fine.
But if I now want to insert data ("INSERT INTO") into this table, it fails. There are no errors or exceptions by OleDbCommand.ExecuteNonQuery(), transaction commits at the end succesffuly, the database is just empty.
Any ideas why?
connection.Open();
string access_com = "DROP TABLE " + globalPrefix + prefix + TableName;
OleDbCommand execute = new OleDbCommand(access_com, connection);
try
{
execute.ExecuteNonQuery();
}
catch (Exception ex)
{
ConfigDataSet.Log.AddLogRow("The program cannot drop table you want. Close the file with it and run program again!", 1);
return 1;
}
access_com = "CREATE TABLE [" + globalPrefix + prefix + TableName + "]" + fieldString + ")";// CONSTRAINT PK" + TableName + " PRIMARY KEY " + primaryKey + ")";
execute.CommandText = access_com;
execute.ExecuteNonQuery();
OleDbTransaction transaction = connection.BeginTransaction();
access_com = "INSERT INTO " + TableName + "( " + allfields + ")" + " VALUES (" + parametersString + ")";
OleDbCommand execute = new OleDbCommand(access_com, connection);
execute.Transaction = transaction;
try
{
execute.ExecuteNonQuery();
execute.Parameters.Clear();
}
catch (OleDbException ex)
{
ConfigDataSet.Log.AddLogRow("Inserting row failed: ", 2);
failedInsertions++;
}
You have the INSERT query in a transaction, but I don't see a commit anywhere in your code:
execute.ExecuteNonQuery();
transaction.Commit();
You should probably also have the transaction.Rollback(); in your exception block. See OleDbConnection.BeginTransaction Method
Related
I've a problem with SqlConnection in C#. I do a large number of INSERT NonQuery, but in any case SqlConnection save in the database always the first 573 rows. This is the method I use for queries. In this method there is a lock because I use different thread to save the data.
public void InsertElement(string link, string titolo, string text)
{
string conString = "*****************";
using (SqlConnection connection = new SqlConnection(conString))
{
connection.Open();
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
}
This is the code of the loop that call the method InsertElement()
public void Save()
{
string[] DatiLetti;
string url = "";
while (result.Count > 0)
{
try
{
url = result.Last();
result.RemoveAt(result.Count - 1);
DatiLetti = ex.DirectExtractText(url);
if (DatiLetti[0].Length > 2)
{
ssc.InsertGare(url, DatiLetti[0], DatiLetti[1]);
}
}
catch (Exception exc)
{
logger.Error("Exception SpiderSave> " + exc);
}
}
}
Result is a volatile array that is progressively filled from other thread. I'm sure that the array contains more than 573 items.
I try to search one solution, but all the answers say that the number of database connections for SQLServer is over 32K at a time and I've already checked this number in my database. Is there anyone who can help me understand the problem?
Don't open a connection for every insert. Use one connection, then pass that connection through to your insert, like this :
public void InsertElement(string link, string titolo, string text, SqlConnection conn)
{
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
I recommend also looking at paramatizing your query, as well as using bulk inserts, and not individual inserts
If you are executing InsertElement() once for each rows of data to insert, then the execution will be too slow for large no. of rows. (Also, you are creating SqlConnection for each query execution.) Try adding many rows at once using a single INSERT query:
INSERT INTO tablename
(c1,c2,c3)
VALUES
(v1,v2,v3),
(v4,v5,v6)
...
try
{
int i = 0;
using (SqlConnection sqlCon = new SqlConnection(Form1.connectionString))
{
string commandString = "INSERT INTO Logindetail (Account,ID,Logint,Logoutt) values ('" + acc + "'," + textbxID.Text + "," + null + ", SYSDATETIME()" + ");";
// MessageBox.Show(commandString);
SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon);
sqlCon.Open();
SqlDataReader dr = sqlCmd.ExecuteReader();
i = 1;
if (i == 0)
{
MessageBox.Show("Error in Logging In!", "Error");
}
MessageBox.Show("Successfully Logged In");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
I'm making a LoginForm for a Project.I have created a table which shows the LoginDetails(Account,ID,LoginTime,LogoutTime).But when I run the Program,it doesn't runs successfully.I face an error which is in Pic-2.When I remove sql 'data reader',the program runs without displaying the error.
When you concatenate a null it basically adds nothing to the string, so this code:
string commandString = "INSERT INTO Logindetail (Account,ID,Logint,Logoutt) values ('" + acc + "'," + textbxID.Text + "," + null + ", SYSDATETIME()" + ");";
results of this string, and as you can see it has an extra comma, that causes the exception:
"INSERT INTO Logindetail (Account,ID,Logint,Logoutt) values ('acc',textbxID,, SYSDATETIME());"
If you want to add NULL to the query it has to be a string, so do this instead:
string commandString = "INSERT INTO Logindetail (Account,ID,Logint,Logoutt) values ('" + acc + "'," + textbxID + ", NULL , SYSDATETIME()" + ");";
And you are using ExecuteReader instead of ExecuteNonQuery. You cannot use ExecuteReader for inserting rows to the DB.
Also, as someone mentioned in the other answer, you better do it with parametes to avoid SQL Injections.
I am trying to pass an insert statement in a C# Winforms to SQL Server. I keep getting a syntax error that just doesn't make sense to me
error in syntax near "("
My syntax is perfectly fine, as when I copy and paste into SQL Server Mgmt Studio, the code runs perfectly.
Any help would be greatly appreciated!
Thanks!
try
{
using (var cmd = new SqlCommand("INSERT INTO " + intodrop.SelectedText + "(" + colnamedrop.SelectedText.ToString() + "," +
colnamedrop2.SelectedText.ToString() + ") " + "VALUES" + " (" + valuebox.Text + ");"))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#tbl", intodrop.SelectedText);
cmd.Parameters.AddWithValue("#colname", colnamedrop.SelectedText);
cmd.Parameters.AddWithValue("#values", valuebox.Text);
cmd.Parameters.AddWithValue("#colname2", colnamedrop2.SelectedText);
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}
Check if SelectedText property returns right values. Try to use Text property instead.
var cmd = new SqlCommand("INSERT INTO " + intodrop.Text +
"(" + colnamedrop.Text + ',' + colnamedrop2.Text + ") "
+ "VALUES" + " (" + valuebox.Text + ");")
You missed comma between column names when insert sql statement preparing. When printing you have comma and display correctly.
Concatenated sql statement without any inputs validation is widely open for sql injection attacks. Try to use parameter as much as possible.
It looks like you are trying to insert values to two columns, but you are appending them like this "Col1+Col2", instead of "Col1+','+Col2".
using (var cmd = new SqlCommand("INSERT INTO " + intodrop.SelectedText + "(" + colnamedrop.SelectedText.ToString() + ','+
colnamedrop2.SelectedText.ToString() + ") " + "VALUES" + " (" + valuebox.Text + ");"))
I hope this resolves the issue.
First try hard coding your insert value after that change it based on your need. Confirm the column data types are assigned correctly.
try
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO Property ( FolioNo,PropertyType) VALUES (001,'WIP')"))
{
cmd.Connection = con;
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}
1) You should have two texbox for entering your values. If no column names you gray the value of column 1, ditto for column 2.
This allows you not to have to enter quote (do not forget to make an escape quotes
2) use the string.format function for more readability
try
{
//Add columns selected
List<string> Mycolumns = new List<string>();
If (! string.IsNullOrEmpty(colnamedrop.Text)) Mycolumns.Add(colnamedrop.Text);
If (! string.IsNullOrEmpty(colnamedrop2.Text)) Mycolumns.Add(colnamedrop2.Text);
//Add values selected with escaped quoted and string quoted
List<string> Myvalues = new List<string>();
If (! string.IsNullOrEmpty(colvalue1.Text)) Myvalues.Add("'" + colvalue1.Text.Replace("'", "''") + "'");
If (! string.IsNullOrEmpty(colvalue2.Text)) Myvalues.Add("'" + colvalue2.Text.Replace("'", "''") + "'");
//If nothing selected, no action
if (Mycolumns.Count==0 && Myvalues.Count==0) return;
//Build query
String Query = string.Format ( "INSERT INTO {0} ({1}) VALUES ({2})", intodrop.Text, string.Join(Mycolumns, ", "), string.Join(Myvalues, ", "));
//Execute query
using (var cmd = new SqlCommand(Query, con ))
{
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
con.Close();
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}
To get more familiar with both c# and ms sql, I made a key generator which is working good. But I want to store they key at a database so I made a method that runs a query and it should store the key(I thought)
This is my method:
public SqlDataReader InsertInto(string tableName, string[] values)
{
string query = "";
try
{
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "')";
for (int i = 1; i < values.Length; ++i)
query += ", '" + values[i] + "'";
query += ")";
}
catch
{
// ignored
}
return ExecuteQuery(query);
}
And this is the code where I execute my query:
private SqlDataReader ExecuteQuery(string query)
{
SqlConnection connection = null;
SqlDataReader dataReader = null;
try
{
using (connection = new SqlConnection(Hash.RunDecryption()))
{
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
using (dataReader = command.ExecuteReader())
{
}
}
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Failed to execute data! " + ex.Message, "Error!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
dataReader?.Close();
CloseConnection(connection);
}
finally
{
dataReader?.Close();
CloseConnection(connection);
}
return dataReader;
}
And the query that is being generated is this INSERT INTO Keys VALUES('fap0zkxbvw3')
But I get the following error:
Failed to execute data! Incorrect syntax near ')'.
The immediate problem is that you have 1 too many closing brackets:
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "')";
should be
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "'";
But you should really look into properly constructing your queries, using parameterizations, stored procedures, etc.
My SQL statement works fine without the delete statement which is my problem.
I use 2 OleDbCommands to call the seperate queries.
This is my current SQL statement in C#:
string mysql = "Insert Into Completed([Batch number], [Product], [Weight]) VALUES('" + batchNumber + "','" + product + "','" + weight + "')";
string newsql = "DELETE FROM Dryers WHERE [Batch number]='"+batchNumber+"'";
This my latest failed attempt in code:
if (conn.State == ConnectionState.Open)
{
try
{
using (System.Transactions.TransactionScope tScope = new TransactionScope())
{
string batchNumber = txtBatchNumber3.Text.ToString();
string product = txtProduct3.Text.ToString();
string weight = txtWeight3.Text.ToString();
string mysql = "Insert Into Packing([Batch number], [Product], [Weight]) VALUES('" + batchNumber + "','" + product + "','" + weight + "') ";
string newsql = "DELETE * FROM Dryers WHERE [Batch number]='" + batchNumber + "'";
OleDbCommand cmd = new OleDbCommand(mysql, conn);
cmd.ExecuteNonQuery();
OleDbCommand cmd2 = new OleDbCommand(newsql, conn);
cmd2.ExecuteNonQuery();
tScope.Complete();
}
MessageBox.Show("Data saved successfuly...!");
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
finally
{
conn.Close();
}
}
else
{
MessageBox.Show("Connection Failed");
}
}
}
}
VS2012 gives the following error:
Failed due toData type mismatch in criteria expression.
You can't do this in Access. You have to call two separate SQL strings.
Use two statements but wrap them in a transaction so it's a single unit of work.
BEGIN TRANSACTION
COMMIT
if you wanted to do it in C# then you would wrap your queries in a transaction scope.
using (System.Transactions.TransactionScope tScope = new TransactionScope())
{
//do work here
//if work is completed
tScope.Complete();
//else do nothing the using statement will dispose the scope and rollback your changes.
}
Here is a walkthrough from Microsoft about making the connection against an access database and querying using ADO.NET.
https://msdn.microsoft.com/en-us/library/ms971485.aspx