Actually im trying to insert as well as update data into datagridview at run time for that i have written one code but while executing it give me Data type No overload for method 'TryParse' takes '1' arguments
my accdb table structure is like below
Field Datatype
Account-- Memo
AccountNumber--Number
Date--Date/Time
Description--Memo
Post_Ref--Memo
Debit--Number
Credit--Number
Balance--Number
**
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
string connectionString = null;
connectionString = ConfigurationManager.ConnectionStrings["AccessConnectionString"].ConnectionString;
con.ConnectionString = connectionString;
string cmd1 = "insert into Ledger([AccountNumber],[Account],[Date],[Description],[Post_Ref],[Debit],[Credit],[Balance])values(?,?,?,?,?,?,?,?)";
OleDbCommand cmd = new OleDbCommand(cmd1, con);
con.Open();
cmd.CommandType = CommandType.Text;
int accountNumber;
bool accountHasValue = int.TryParse(dataGridView1.Rows[e.RowIndex].Cells["AccountNumber"].Value.ToString(), out accountNumber);
if (accountHasValue)
{
cmd.Parameters.AddWithValue("#AccountNumber", accountNumber);
}
string accounts = dataGridView1.Rows[e.RowIndex].Cells["Account"].Value.ToString();
cmd.Parameters.AddWithValue("#Account", accounts);
DateTime datetime;
bool dateTimeHasValue = DateTime.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Date"].Value.ToString(), out datetime);
if (dateTimeHasValue)
{
cmd.Parameters.AddWithValue("#Date", datetime);
}
string Description = dataGridView1.Rows[e.RowIndex].Cells["Description"].Value.ToString();
cmd.Parameters.AddWithValue("#Description", Description);
string Post_Ref = dataGridView1.Rows[e.RowIndex].Cells["Post_Ref"].Value.ToString();
cmd.Parameters.AddWithValue("#Post_Ref", Post_Ref);
int debit;
bool debitHasValue = Int32.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Debit"].Value.ToString(), out debit);
if (debitHasValue)
{
cmd.Parameters.AddWithValue("#Debit", debit);
}
int Credits;
bool CreditsHasValue = Int32.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Credit"].Value.ToString(), out Credits);
if (CreditsHasValue)
{
cmd.Parameters.AddWithValue("#Credit", Credits);
}
int Balances;
bool BalancesHasValue = Int32.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Balance"].Value.ToString(), out Balances);
if (BalancesHasValue)
{
cmd.Parameters.AddWithValue("#Balance", Balances);
}
cmd.ExecuteNonQuery();
con.Close();
Load_data();
}
The error simply means the TryParse method does not have an overload that accepts one parameter. If you look at the documentation, it takes two parameters.
For the lines of code that use TryParse, first declare a variable and use it as out parameter and pass it for seeding your database. Show me the code !!! Ok, see examples below.
//For accountNumber
int accountNumber;
bool accountHasValue = int.TryParse(dataGridView1.Rows[e.RowIndex].Cells["AccountNumber"].Value, out accountNumber);
if(accountHasValue)
{
cmd.Parameters.AddWithValue("#AccountNumber", accountNumber);
}
//For Datetime
DateTime datetime;
bool dateTimeHasValue = DateTime.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Date"].Value, out datetime);
if(dateTimeHasValue)
{
cmd.Parameters.AddWithValue("#Date", datetime);
}
//For Debit
int debit;
bool debitHasValue = Int32.TryParse(dataGridView1.Rows[e.RowIndex].Cells["Debit"].Value, debit);
if(debitHasValue )
{
cmd.Parameters.AddWithValue("#Debit", debit);
}
Basically all lines of code that you use the TryParse, implement them as above.
Related
I have problem when I try to update SQL table with
I have datagridview and I need to update SQL table and take the value form my datagridview . my datagridview have more than 10000 rows
I take time more than 1:30 hour very slow
datagridview name "dgv_balance"
Here is the code:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "My Connection"
cn.Open();
using (SqlCommand cmd_select = new SqlCommand())
{
for (int i = 0; i < dgv_balance.RowCount; i++)
{
cmd_select.Connection = cn;
cmd_select.CommandType = CommandType.StoredProcedure;
cmd_select.CommandText = "clients_balances_select_glid_date";
cmd_select.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_select.Parameters.AddWithValue("#date", Convert.ToDateTime(dgv_balance.Rows[i].Cells[2].Value));
if (cmd_select.ExecuteScalar().ToString()=="")
{
using (SqlCommand cmd_insert = new SqlCommand())
{
cmd_insert.Connection = cn;
cmd_insert.CommandType = CommandType.StoredProcedure;
cmd_insert.CommandText = "clients_balances_insert_data";
cmd_insert.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_insert.Parameters.AddWithValue("#name", Convert.ToString(dgv_balance.Rows[i].Cells[1].Value));
cmd_insert.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_insert.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_insert.ExecuteNonQuery();
cmd_insert.Parameters.Clear();
}
}
else
{
using (SqlCommand cmd_update= new SqlCommand())
{
cmd_update.Connection = cn;
cmd_update.CommandType = CommandType.StoredProcedure;
cmd_update.CommandText = "clients_balances_update_balance";
cmd_update.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_update.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_update.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_update.ExecuteNonQuery();
cmd_update.Parameters.Clear();
}
}
cmd_select.Parameters.Clear();
}
}
}
You may have to call SELECT command for one time only before you loop through your datagridview rows and cache the result data and check on the result while iterating your datagridview instead of calling it on each row. This way you will reduce your commands by 10000.
It also better if you could show us your procedures' queries.
Or if your datagridview is the ONLY source for your data then you can delete all your previous data in your database and make one insert call for all of your datagridview data.
Try this:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "MyConnection" ;
cn.Open();
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
using (SqlCommand cmd_select = new SqlCommand())
{
cmd_select.Connection = cn; cmd_select.CommandType = CommandType.StoredProcedure; cmd_select.CommandText = "clients_balances_select_glid_date";
da.SelectCommand = cmd_select;
da.Fill(dt);
for (int i = 0; i < dgv_balance.RowCount; i++)
{
if(/* check here if dt contains this row*/)
{
// Insert
}
else
{
// Update
}
}
}
}
I think you should insert or update all data one time.
Create index for glId column. If glId is primary key, it's indexed.
Assumes that List ClientBalance is list items you need update or insert.
public class ClientBalance
{
GlId int {get;set;}
ClientName string {get;set;}
Balance decimal {get;set;}
DateInput DateTime {get;set;}
}
You could serialize list Item to xml string and pass it to store procedure
public string Serialize<T>(T value) where T : new()
{
var serializeXml = string.Empty;
if (value != null)
{
try
{
var xmlserializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
var writer = XmlWriter.Create(stringWriter);
xmlserializer.Serialize(writer, value);
serializeXml = stringWriter.ToString();
writer.Close();
}
catch (Exception ex)
{
return string.Empty;
}
}
return serializeXml;
}
Create a new store procedure for insert or update item like that:
CREATE PROCEDURE [dbo].[clients_balances_insert_or_update]
(
#xmlObject nvarchar(max)
)
AS
BEGIN
-- TABLE INCLUDE DATE FROM XML
DECLARE #tblBalances AS TABLE
(
GlId int,
DateInput datetime,
ClientName nvarchar(50),
Balance decimal(18,2)
)
DECLARE #idoc int -- xml id
-- PARSE XML TO OBJECT
EXEC sp_xml_preparedocument #idoc OUTPUT, #xmlObject
INSERT INTO #tblBalances
(
GlId, DateInput, ClientName, Balance
)
SELECT s.GlId, s.DateInput, s.ClientName, s.Balance
FROM OPENXML (#idoc, '/ArrayOfClientBalance/ClientBalance', 8) WITH (
GlId int 'GlId',
DateInput datetime 'DateInput',
ClientName NVARCHAR(50) 'ClientName',
Balance DECIMAL(18,2) 'Balance'
) s
EXEC sp_xml_removedocument #idoc
-- USE MERGE FOR INSERT OR UPDATE DATE
-- Use transaction
BEGIN TRAN InsertOrUpdate
BEGIN TRY
MERGE Target AS T
USING #tblBalances AS S
ON (T.GlId = S.GlId)
WHEN NOT MATCHED BY TARGET
THEN INSERT( GlId, DateInput, ClientName, Balance) VALUES( GlId, DateInput, ClientName, Balance)
WHEN MATCHED
THEN UPDATE SET DateInput = S.DateInput, Balance = s.Balance
COMMIT TRAN InsertOrUpdate;
END TRY
BEGIN CATCH
ROLLBACK TRAN InsertOrUpdate;
THROW;
END CATCH
END
Hope this helpfully!
can you please guys help me, i'm having trouble on making my primary key into auto-increment, My table name is books and the column that i want to be auto-increment is serial_no which is a primary key.
public class donate extends javax.swing.JFrame {
Connection con;
Statement stmt;
ResultSet rs;
PreparedStatement pst;
DefaultTableModel loginModel = new DefaultTableModel();
int curRow = 0;
/**
* Creates new form donate
*/
public donate() {
initComponents();
DoConnect();
showAll();
}
void showAll(){
try{
rs = stmt.executeQuery("SELECT * FROM books");
while(rs.next())
{
String book = rs.getString("book_title");
String categorie = rs.getString("category");
String status = rs.getString("book_status");
String donators = rs.getString("donator");
int serial_nos = rs.getInt("serial_no");
loginModel.addRow(new Object[]{book, categorie, status, donators, serial_nos});
}
}catch(SQLException err){
System.out.println(err);
}
}
void DoConnect( ) {
try{
//CONNECT TO THE DATABASE
String host = "jdbc:derby://localhost:1527/Dafuq7";
String uName ="Dafuq7";
String uPass ="Dafuq7";
con = DriverManager.getConnection(host, uName, uPass);
//EXECUTE SOME SQL AND LOAD THE RECORDS INTO THE RESULTSET
stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM books";
rs = stmt.executeQuery(sql);
}
catch(SQLException err){
JOptionPane.showMessageDialog(donate.this, err.getMessage());
}
}
and here is for may button, which when i input all the data will be submitted to my table books
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String bookttl = bookt.getText();
String yourn = yn.getText();
String categ = cat.getSelectedItem().toString();
String bstat = bs.getSelectedItem().toString();
try {
rs.moveToInsertRow();
rs.updateString( "book_title", bookttl );
rs.updateString( "category", yourn );
rs.updateString( "book_status", categ );
rs.updateString( "donator", bstat );
loginModel.addRow(new Object[]{bookttl, yourn, categ, bstat});
rs.insertRow( );
stmt.close();
rs.close();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM books";
rs = stmt.executeQuery(sql);
}
catch (SQLException err) {
System.out.println(err.getMessage() );
}// TODO add your handling code here:
}
BTW i found another way around by doing this, grabbing my table and reconstructing it and put this code in the create table script
SERIAL_NO INTEGER default AUTOINCREMENT: start 1 increment 1 not null primary key
Simply define your serial_no column as int primary key generated always as identity and then Derby will automatically assign the numbers for you. Here is some example code:
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(
"jdbc:derby:C:/__tmp/derbytest;create=true")) {
String sql;
sql = "DROP TABLE books";
try (Statement s = conn.createStatement()) {
s.executeUpdate(sql);
} catch (Exception e) {
// assume table did not previously exist
}
sql = "CREATE TABLE books (" +
"serial_no int primary key " +
"generated always as identity, " +
"title varchar(100))";
try (Statement s = conn.createStatement()) {
s.executeUpdate(sql);
}
sql = "INSERT INTO books (title) VALUES (?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "The Book of Foo");
ps.executeUpdate();
ps.setString(1, "The Book of Bar");
ps.executeUpdate();
ps.setString(1, "The Book of Baz");
ps.executeUpdate();
}
sql = "SELECT * FROM books";
try (Statement s = conn.createStatement()) {
try (ResultSet rs = s.executeQuery(sql)) {
while (rs.next()) {
System.out.println(String.format(
"%d: %s",
rs.getInt("serial_no"),
rs.getString("title")));
}
}
}
} catch (SQLException se) {
se.printStackTrace(System.out);
System.exit(0);
}
}
which produces
1: The Book of Foo
2: The Book of Bar
3: The Book of Baz
I am trying to update a few columns in a Oracle table from my C# code.
Here is my method:
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
whereClause = String.Format(whereClause, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), whereClause);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
cmd.ExecuteNonQuery();
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
Here is the Query:
UPDATE
{0}
SET
SYNC_STATUS = '{1}'
,SYNC_DATE = TO_DATE('{2}', 'yyyy/mm/dd')
{3}
And the where clause will look something like:
WHERE ID = {0}
This method updates about 10 records, and the rest stays null. This mehod does return true, and I have debugged, no exception is thrown.
Why does it not update all records?
This isn't an answer but might help debug the problem.
Instead of the like:
cmd.ExecuteNonQuery();
put in this:
int count = cmd.ExecuteNonQuery();
if (count == 0)
{
Console.WriteLine("");
}
Put a break on the Console.WriteLine("") and run it. The debugger will stop if no rows were updated. You can then check the query, and whether or not that ID actually exists.
The problem was with the WHERE clause. Since it contains a place holder {0}, after I I formatted the WHERE clause, the ID always stayed to the value it was formatted with first.
This is what my new method looks like.
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
string originalWhere = whereClause;
originalWhere = String.Format(originalWhere, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), originalWhere);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
bool success = cmd.ExecuteNonQuery() > 0;
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
As can be seen, I added a variable 'originalWhere', that gets formatted, but most importantly, is being set to original WHERE clause parameter passed, so that it will always contain the place holder.
Where is the problem in my code?
I use a stored procedure and transaction.
For one parameter to be working properly, but when the number of parameters is more than one error occurs.
Where is my problem?
This is my code in C#
internal static bool ExecuteNonQueryTransaction(string CommandName, CommandType cmdType, SqlParameter[][] pars)
{
int result = 0;
SqlTransaction tr = null;
int h = pars.GetLength(0);
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
try
{
tr = con.BeginTransaction();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = cmdType;
cmd.Transaction = tr;
cmd.CommandText = CommandName;
// cmd.Parameters.AddRange(pars);
for (int i = 0; i < pars.GetLength(0); i++)
{
cmd.Parameters.AddRange(pars[i]);
cmd.ExecuteNonQuery();
}
tr.Commit();
}
}
catch
{
if (tr != null)
{
tr.Rollback();
}
//return false;
}
}
return (result > 0);
}
and this my stored procedure
ALTER PROCEDURE dbo.AddNewUserTypePageAccess
(#id_user_type int,
#id_page_access int)
as
insert into user_type_page_access(id_user_type, id_page_access)
values(#id_user_type, #id_page_access)
return
Thank you for your help.....
You shouldn't call ExecuteNonQuery(); inside the loop that adds the parameters! Add all parameters, and then call ExecuteNonQuery(); once, with all the parameters in place.
Use this code:
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = cmdType;
cmd.Transaction = tr;
cmd.CommandText = CommandName;
// cmd.Parameters.AddRange(pars);
for (int i = 0; i < pars.GetLength(0); i++)
{
cmd.Parameters.AddRange(pars[i]);
}
// call ExecuteNonQuery only AFTER you've added all the parameters!
cmd.ExecuteNonQuery();
tr.Commit();
}
I had the error in this code snippet:
private String[][] connectToDB(String query) throws ClassNotFoundException{
String[][] results = null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String db = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=E:/EACA_AgroVentures1.accdb";
conn = DriverManager.getConnection(db);
stmt = conn.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsm = rs.getMetaData();
rs.beforeFirst();
int columns = rsm.getColumnCount();
int rows = getRowCount(rs);
//int rows = rs.getFetchSize();
int rowCount = 0;
results = new String[rows][columns];
//System.out.println(rows+" "+columns);
while((rs!=null) && (rs.next())){
for(int i = 1; i < columns; i++){
results[rowCount][i-1] = rs.getString(i); // --> ERROR SHOWS HERE
//System.out.println(rowCount+","+i+" = "+rs.getString(i));
}
rowCount++;
}
rs.getStatement().close();
conn.close();
} catch (SQLException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
return results;
}
My query consists of the following:
private void loadMR(){
try {
String query = "SELECT dealerCode, SUM(kg) AS totalKG, SUM(price) AS totalPrice, returnDate, BID FROM meatReturns GROUP BY BID, dealerCode, returnDate;";
Object[][] result = connectToDB(query);
// some more code below..
I tried using the first code with some other query given in another method:
private void loadDealers(){
try {
String query = "SELECT * FROM Dealers";
Object[][] result = connectToDBWithRows(
query);
// some more code..
and it runs perfectly well. What is going on here? How can i fix this problem?
UPDATE: the only difference of connectToDBWithRows and connectToDB is the while loop that manages the resultSet
// Snippet from connectToDBWithRows()
while((rs!=null) && (rs.next())){
for(int i = 0; i < columns; i++){
if (i == 0){
// Do nothing
}else{
results[rowCount][i] = rs.getString(i);
//System.out.println(rowCount+","+i+" = "+rs.getString(i));
}
}
rowCount++;
}
and this is my getRowCount() method
private int getRowCount(ResultSet resultSet){
int size = 0;
try {
resultSet.last();
size = resultSet.getRow();
resultSet.beforeFirst();
}
catch(Exception ex) {
return 0;
}
return size;
}
I've noticed that sometimes, Access needs you to specify the table name when referring to columns in sql statements. Try the following:
private void loadMR(){
try {
String query = "SELECT meatReturns.dealerCode, SUM(meatReturns.kg) AS totalKG, SUM(meatReturns.price) AS totalPrice, meatReturns.returnDate, meatReturns.BID FROM meatReturns GROUP BY meatReturns.BID, meatReturns.dealerCode, meatReturns.returnDate";
Object[][] result = connectToDBWithRows(query);