I'm trying to delete all data from Table where index=Textbox1.Text and idnmb=Textbox2.Text
When I remove this part + "AND id_nmb = " + data2 it works but not what I want.
I have this code :
private void button1_Click(object sender, RoutedEventArgs e)
{
var data1 = this.textBox1.Text;
var data2 = this.textBox2.Text;
OleDbCommand cmd = new OleDbCommand("DELETE FROM Table WHERE index = " + data1 + "AND idnmb = " + data2 , con);
cmd.Connection = con;
int temp = cmd.ExecuteNonQuery();
if (temp > 0)
{
MessageBox.Show("OK !");
}
else
{
MessageBox.Show("Some error !");
}
}
}
It gives me this message : No value given for one or more required parameters.
Any idea how to solve this ?
The short answer is likely that you need a space before AND in your string. It looks like you assume numbers will be entered in each of the textboxes, but you don't enforce that, so different errors may occur depending on the content of those textboxes.
The longer answer is DON'T DO IT THIS WAY! You're opening up your code to SQL Injection attacks. Use parameterized queries instead as shown in this reference.
Related
Ok , I"m doing what looks like a simple Dapper query
but if I pass in my studId parameter, it blows up with this low level networking exception:
{"A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied."}
if I comment out the line of sql that uses it, fix the where clause, ,and comment out the line where it's added the the parameters object. It retrieves rows as expected.
I've spent the last 2.5 days trying everything I could think of, changing the names to match common naming patterns, changing type to a string (just gave a error converting string to number), yadda yadda yadda..
I'm at a complete loss as to why it doesn't like that parameter, I look at other code that works and they pass Id's just fine...
At this point I figure it has to be an ID-10-t that's staring me in the face and I'm just assuming my way right past it with out seeing it.
Any help is appreciated
public List<StudDistLearnSchedRawResponse> GetStudDistanceLearningScheduleRaw( StudDistLearnSchedQueryParam inputs )
{
var aseSqlConnectionString = Configuration.GetConnectionString( "SybaseDBDapper" );
string mainSql = " SELECT " +
" enrollment.stud_id, " +
" sched_start_dt, " +
" sched_end_dt, " +
" code.code_desc, " +
" student_schedule_dl.enrtype_id, " +
" student_schedule_dl.stud_sched_dl_id, " +
" dl_correspond_cd, " +
" course.course_name, " +
" stud_course_sched_dl.sched_hours, " +
" actual_hours, " +
" course_comments as staff_remarks, " + // note this column rename - EWB
" stud_course_sched_dl.sched_item_id , " +
" stud_course_sched_dl.stud_course_sched_dl_id " +
" from stud_course_sched_dl " +
" join student_schedule_dl on student_schedule_dl.stud_sched_dl_id = stud_course_sched_dl.stud_sched_dl_id " +
" join course on stud_course_sched_dl.sched_item_id = course.sched_item_id " +
" left join code on student_schedule_dl.dl_correspond_cd = code.code_id " +
" join enrollment_type on student_schedule_dl.enrtype_id = enrollment_type.enrtype_id " +
" join enrollment on enrollment_type.enr_id = enrollment.enr_id " +
" where enrollment.stud_id = #studId " +
" and sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
DapperTools.DapperCustomMapping<StudDistLearnSchedRawResponse>();
//string sql = query.ToString();
DateTime? startOfWeek = StartOfWeek( inputs.weekStartDateTime, DayOfWeek.Monday );
DateTime? startOfNextWeek = StartOfWeek( inputs.weekStartDateTime.Value.AddDays( 7 ) , DayOfWeek.Monday );
try
{
using ( IDbConnection db = new AseConnection( aseSqlConnectionString ) )
{
db.Open();
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
List<StudDistLearnSchedRawResponse> list = new List<StudDistLearnSchedRawResponse>();
list = db.Query<StudDistLearnSchedRawResponse>( mainSql, arguments ).ToList();
return list;
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
return null;
}
}
Here is the input object
public class StudDistLearnSchedQueryParam
{
public Int64 StudId;
public DateTime? weekStartDateTime;
}
Here is the dapper tools object which just abstracts some ugly code to look nicer.
namespace EricSandboxVue.Utilities
{
public interface IDapperTools
{
string ASEConnectionString { get; }
AseConnection _aseconnection { get; }
void ReportSqlError( ILogger DalLog, string sql, Exception errorFound );
void DapperCustomMapping< T >( );
}
public class DapperTools : IDapperTools
{
public readonly string _aseconnectionString;
public string ASEConnectionString => _aseconnectionString;
public AseConnection _aseconnection
{
get
{
return new AseConnection( _aseconnectionString );
}
}
public DapperTools( )
{
_aseconnectionString = Environment.GetEnvironmentVariable( "EIS_ASESQL_CONNECTIONSTRING" );
}
public void ReportSqlError( ILogger DalLog, string sql, Exception errorFound )
{
DalLog.LogError( "Error in Sql" );
DalLog.LogError( errorFound.Message );
//if (env.IsDevelopment())
//{
DalLog.LogError( sql );
//}
throw errorFound;
}
public void DapperCustomMapping< T >( )
{
// custom mapping
var map = new CustomPropertyTypeMap(
typeof( T ),
( type, columnName ) => type.GetProperties( ).FirstOrDefault( prop => GetDescriptionFromAttribute( prop ) == columnName )
);
SqlMapper.SetTypeMap( typeof( T ), map );
}
private string GetDescriptionFromAttribute( System.Reflection.MemberInfo member )
{
if ( member == null ) return null;
var attrib = (Dapper.ColumnAttribute) Attribute.GetCustomAttribute( member, typeof(Dapper.ColumnAttribute), false );
return attrib == null ? null : attrib.Name;
}
}
}
If I change the SQL string building to this(below), but leave everything else the same(Including StudId in the args struct)... it doesn't crash and retrieves rows, so it's clearly about the substitution of #studId...
// " where enrollment.stud_id = #studId " +
" where sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
You name your data members wrong. I had no idea starting a variable name with # was possible.
The problem is here:
var arguments = new
{
#studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
#startOfWeek = startOfWeek.Value.ToShortDateString(),
#startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
It should have been:
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
The # is just a hint to Dapper, that it should replace with a corresponding member name.
## has special meaning in some SQL dialects, that's probably what makes the trouble.
So here's what I Found out.
The Sybase implementation has a hard time with Arguments.
It especially has a hard time with arguments of type int64 (this existed way pre .NetCore)
So If you change the type of the passed in argument from int64 to int32, everything works fine.
You can cast it, or just change the type of the method parameter
I am writing methods through JDBC to create a table and a sequence to recall in a Trigger, I want to set up an id column which auto-increments before every insert on the table. I succeeded in building both the createTable method and the createSequence method in the DAO, but when I run the method to create the Trigger I got the java.sql.SQLException: Missing IN or OUT parameter at index:: 1
public void createTrigger() {
PreparedStatement ps;
StringBuilder queryTrigger = new StringBuilder();
queryTrigger.append("CREATE OR REPLACE TRIGGER ");
queryTrigger.append(Tables.getInstance().getName() + "_INSERTED\n");
queryTrigger.append("BEFORE INSERT ON " + Tabelle.getInstance().getName());
queryTrigger.append("\nFOR EACH ROW\n");
queryTrigger.append("BEGIN\n");
queryTrigger.append("SELECT " + Tables.getInstance().getName() + "SEQ.NEXTVAL\n");
queryTrigger.append("INTO :new.id\n");
queryTrigger.append("FROM dual;\n ");
queryTrigger.append("END;\n");
queryTrigger.append("/\n");
queryTrigger.append("ALTER TRIGGER " +Tabelle.getInstance().getName() + "_INSERTED ENABLE\n");
queryTrigger.append("/\n");
String stringQueryTrigger = queryTrigger.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(stringQueryTrigger);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);}
Here instead the creation of the table does actually work even if I don't
write the classic lines with parametrized "?" for the preparedStatement.setString(index, String)
public void createTable(Columns c) {
PreparedStatement ps;
StringBuilder query = new StringBuilder();
query.append("CREATE TABLE " + Tabelle.getInstance().getName() + "(");
query.append(Columns.getInstance().getColumnName() + " ");
query.append(Columns.getInstance().getDataType());
if(Columns.getInstance().isNullOrNot() == true) {
query.append(" NOT NULL");
}
else {
query.append("");
}
if(Columns.getInstance().isPrimaryKeyOrNot() == true) {
query.append(" PRIMARY KEY)");
}
else {
query.append(")");
}
String queryToString = query.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(queryToString);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);
}
//EDIT
turns out that is enough to substitute the PreparedStatement with a simple Statement, to get rid of the indexes mechanism and get the DB to accept the query
I would suggest creating an auto-increment sequnce in oracle that can be used for all ids and just add the string id.NextVal to the string query
What I mean is:
Rem in oracle create sequence
CREATE SEQUENCE ID
START BY 1
INCREMENT 1
// in java to execute query
String query = "INSERT INTO TABLE VALUES(ID.NEXTVAL);" ;
//rest of code
Hello guys whenever I try to delete a row using a radiobutton, I get both try and catch messages, when it is supposed to be just 1 of them, I have this code
Here's my calling button method
if(request.getParameter("btnEliminar") != null)
{
String value;
int codParse;
OC_DAO objDAO = new OC_DAO();
valor = request.getParameter("rbSel");
codParse = Integer.parseInt(valor);
objDAO.DeleteRow(codParse);
}
Here's my java code
public void DeleteRow(int codDet)
{
try
{
cn = Conexion.getConexion();
pt = cn.prepareStatement("DELETE "
+ "FROM detalleProd "
+ "WHERE codDet = ?");
pt.setInt(1, codDet);
pt.executeUpdate();
System.out.println("ROW DELETED ON CODDET: " + codDet);
rs.close();
pt.close();
cn.close();
}
catch(Exception exc)
{
System.out.println("Error while deleting");
System.out.println(exc.toString());
}
}
And here's my log
Información: ROW DELETED ON CODDET: 48
Información: Error while deleting
Información: java.lang.NullPointerException
The reason is due to rs.close();, you have not set value of rs,it's null and can not be closed,you just need to remove this line of code.
Your code seems very strange,I do not have see where you declare rs,it will compile error in your IDE.
I try to refresh the data of jTable upon deletion of selected row. Here are my codes to set up table :
private JTable getJTableManageReplies() {
jTableManageReplies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTableManageReplies.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(
viewRow, 0).toString());
eForumRepliesAdmin reply = new eForumRepliesAdmin(replyID);
replyID = JOptionPane.showConfirmDialog(null, "Are you sure that you want to delete the selected reply? " , "Delete replies", JOptionPane.YES_NO_OPTION);
if(replyID == JOptionPane.YES_OPTION){
reply.deleteReply();
JOptionPane.showMessageDialog(null, "Reply has been deleted successfully.");
SetUpJTableManageReplies();
}
}
}
});
return jTableManageReplies;
}
public void SetUpJTableManageReplies() {
DefaultTableModel tableModel = (DefaultTableModel) jTableManageReplies
.getModel();
String[] data = new String[5];
db.setUp("IT Innovation Project");
String sql = "Select forumReplies.reply_ID,forumReplies.reply_topic,forumTopics.topic_title,forumReplies.reply_content,forumReplies.reply_by from forumReplies,forumTopics WHERE forumReplies.reply_topic = forumTopics.topic_id ";
ResultSet resultSet = null;
resultSet = db.readRequest(sql);
jTableManageReplies.repaint();
tableModel.getDataVector().removeAllElements();
try {
while (resultSet.next()) {
data[0] = resultSet.getString("reply_ID");
data[1] = resultSet.getString("reply_topic");
data[2] = resultSet.getString("topic_title");
data[3] = resultSet.getString("reply_content");
data[4] = resultSet.getString("reply_by");
tableModel.addRow(data);
}
resultSet.close();
} catch (Exception e) {
System.out.println(e);
}
}
And this is my sql statement :
public boolean deleteReply() {
boolean success = false;
DBController db = new DBController();
db.setUp("IT Innovation Project");
String sql = "DELETE FROM forumReplies where reply_ID = " + replyID
+ "";
if (db.updateRequest(sql) == 1)
success = true;
db.terminate();
return success;
}
I called the repaint() to update the table data with the newest data in database and it works. I mean the data after deletion of certain row. However, the existing posts will keep on re-add. Then I add the removeAllElement method to remove all the existing posts because my sql statement is select * from table. Then, there is an error message which is ArrayIndexOutOfBoundsException. Any guides to fix this? Thanks in advance.
I called the repaint() to update the table data with the newest data
in database and it works.
There is no need to call repaint method when data is changed. Data change is handled by the Table Model (DefaultTableModel in this case.) And fireXXXMethods are required to be called whenever data is changed but you are using DefaultTableModel even those are not required. (Since by default it call these methods when ever there is a change.)
I think the problem is in the valuesChanged(..) method. You are getting the value at row 0 but not checking whether table has rows or not. So keep a constraint.
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
if(jTableManageReplies.getRowCount() > 0)
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(viewRow, 0).toString());
I have run into the following error message at run-time with my novice's Sql / Visual C# database program:
Concurrency violation: the UpdateCommand affected 0 of the expected 1 records.
I have done some searching around about this issue and have seen several threads about it, but they aren't enough for me to resolve the issue. I noticed people talking about how it can often occur when you're using an auto-incrementing primary key. That is the case in this program. Also there is no multithreading or anything else like that that I am coding into this program. Therefore I think the auto-increment is possibly the only problem.
That being said, how do I get the update command to work, despite the auto-increment? I can hardly stand on two feet when it comes to database programming, so please be detailed, if you don't mind. Also the command I'm using is via a SqlCommandBuilder object. I have set that object to new SqlCommandBuilder(DataAdapter), and I have not done anything special with it.
Thanks.
This edit is the second one. The first one is below.
Due to my inexperience with database programming, I am unable to say this for sure. However I have good reason to believe that the problem I am experiencing has to do with new rows not getting added to the database completely until the program terminates. I do not understand why they are waiting until program termination to do that, or if they are waiting until then, just what exactly what about the program's termination causes them to suddenly get saved completely. However I have forgotten to mention that this error only occurs on rows that I have added during that specific execution of the program. If the row was already added on a previous execution or through pre-existing table data, everything's fine. I am getting the same error with the delete method, and it also only occurs with new rows.
How do I get these rows to be fully saved to everything so that this doesn't happen? What about the program's termination is causing these rows to get fully saved? Thanks!
Due to a request, I have left here two code snippets. The first one will be the method in which the the problem occurs. The next one will include the entire class. There are only two classes in the entire program, and the other class doesn't seem important to me in this particular issue.
private void btnUpdate_Click(object sender, EventArgs e)
{
if (recordShown)
{
con.Open();
currentRow[1] = tbFirstName.Text;
currentRow[2] = tbMiddleName.Text;
currentRow[3] = tbLastName.Text;
currentRow[4] = tbSuffix.Text;
currentRow[5] = tbHomePhone.Text;
currentRow[6] = tbCellPhone.Text;
currentRow[7] = tbOtherPhone.Text;
currentRow[8] = tbStreetAddress.Text;
currentRow[9] = tbCityAndState.Text;
currentRow[10] = tbCountry.Text;
currentRow[11] = tbEmail.Text;
dAdapter.Update(dataset, "Contacts");
con.Close();
}
else
{
MessageBox.Show("Please locate/add a record first.");
}
}
Next snippet:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace Dakota
{
public partial class Form1 : Form
{
SqlConnection con;
DataSet dataset;
SqlDataAdapter dAdapter;
DataRow currentRow;
string primaryKey;
SqlCommandBuilder cmdBuilder;
bool recordShown = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dataset = new DataSet();
con = new SqlConnection();
con.ConnectionString = "Data Source=.\\SQLEXPRESS;" +
"AttachDbFilename=C:\\Users\\Sterling\\Documents\\Contacts.mdf;" +
"Integrated Security=True;Connect Timeout=30;User Instance=True";
con.Open();
string getData = "SELECT * FROM tblContacts";
dAdapter = new SqlDataAdapter(getData, con);
dAdapter.Fill(dataset, "Contacts");
cmdBuilder = new SqlCommandBuilder(dAdapter);
cmdBuilder.ConflictOption = ConflictOption.OverwriteChanges;
con.Close();
}
private void clearTextBoxes()
{
tbFirstName.Clear();
tbMiddleName.Clear();
tbLastName.Clear();
tbSuffix.Clear();
tbHomePhone.Clear();
tbCellPhone.Clear();
tbOtherPhone.Clear();
tbStreetAddress.Clear();
tbCityAndState.Clear();
tbCountry.Clear();
tbEmail.Clear();
}
private void fillTextBoxes(int row)
{
DataRow dr = dataset.Tables["Contacts"].Rows[row];
tbFirstName.Text = dr.ItemArray.GetValue(1).ToString();
tbMiddleName.Text = dr.ItemArray.GetValue(2).ToString();
tbLastName.Text = dr.ItemArray.GetValue(3).ToString();
tbSuffix.Text = dr.ItemArray.GetValue(4).ToString();
tbHomePhone.Text = dr.ItemArray.GetValue(5).ToString();
tbCellPhone.Text = dr.ItemArray.GetValue(6).ToString();
tbOtherPhone.Text = dr.ItemArray.GetValue(7).ToString();
tbStreetAddress.Text = dr.ItemArray.GetValue(8).ToString();
tbCityAndState.Text = dr.ItemArray.GetValue(9).ToString();
tbCountry.Text = dr.ItemArray.GetValue(10).ToString();
tbEmail.Text = dr.ItemArray.GetValue(11).ToString();
}
private void fillTextBoxes(DataRow dr)
{
tbFirstName.Text = dr.ItemArray.GetValue(1).ToString();
tbMiddleName.Text = dr.ItemArray.GetValue(2).ToString();
tbLastName.Text = dr.ItemArray.GetValue(3).ToString();
tbSuffix.Text = dr.ItemArray.GetValue(4).ToString();
tbHomePhone.Text = dr.ItemArray.GetValue(5).ToString();
tbCellPhone.Text = dr.ItemArray.GetValue(6).ToString();
tbOtherPhone.Text = dr.ItemArray.GetValue(7).ToString();
tbStreetAddress.Text = dr.ItemArray.GetValue(8).ToString();
tbCityAndState.Text = dr.ItemArray.GetValue(9).ToString();
tbCountry.Text = dr.ItemArray.GetValue(10).ToString();
tbEmail.Text = dr.ItemArray.GetValue(11).ToString();
}
private void btnSearch_Click(object sender, EventArgs e)
{
string searchFor = tbSearchFor.Text;
string column;
if (rbFirstName.Checked)
{
column = "firstName";
}
else
{
column = "lastName";
}
DataRow[] rows = dataset.Tables["Contacts"].Select(column + "='" + searchFor + "'");
int number = rows.Length;
if (number == 0)
{
MessageBox.Show("No such records were found.");
}
else if (number > 1)
{
string[] strings = new string[rows.Length];
for (int i = 0; i < strings.Length; i++)
{
bool hasFirst = false;
bool hasMiddle = false;
strings[i] = "";
if (rows[i].ItemArray.GetValue(1).ToString() != "")
{
hasFirst = true;
strings[i] += rows[i].ItemArray.GetValue(1).ToString();
}
if (rows[i].ItemArray.GetValue(2).ToString() != "")
{
hasMiddle = true;
if (hasFirst)
{
strings[i] += " ";
}
strings[i] += rows[i].ItemArray.GetValue(2).ToString();
}
if (rows[i].ItemArray.GetValue(3).ToString() != "")
{
if ((hasFirst && !hasMiddle) || (hasMiddle))
{
strings[i] += " ";
}
strings[i] += rows[i].ItemArray.GetValue(3).ToString();
}
if (rows[i].ItemArray.GetValue(4).ToString() != "")
{
strings[i] += " " + rows[i].ItemArray.GetValue(4).ToString();
}
}
// int choice;
Form2 form2 = new Form2(strings);
if (form2.ShowDialog(this) == DialogResult.OK)
{
primaryKey = rows[form2.choice].ItemArray.GetValue(0).ToString();
// choice = form2.choice;
fillTextBoxes(rows[form2.choice]);
currentRow = rows[form2.choice];
recordShown = true;
}
}
else
{
primaryKey = rows[0].ItemArray.GetValue(0).ToString();
currentRow = rows[0];
fillTextBoxes(rows[0]);
recordShown = true;
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
con.Open();
DataRow row = dataset.Tables["Contacts"].NewRow();
row[1] = tbFirstName.Text;
row[2] = tbMiddleName.Text;
row[3] = tbLastName.Text;
row[4] = tbSuffix.Text;
row[5] = tbHomePhone.Text;
row[6] = tbCellPhone.Text;
row[7] = tbOtherPhone.Text;
row[8] = tbStreetAddress.Text;
row[9] = tbCityAndState.Text;
row[10] = tbCountry.Text;
row[11] = tbEmail.Text;
currentRow = row;
dataset.Tables["Contacts"].Rows.Add(row);
dAdapter.Update(dataset, "Contacts");
recordShown = true;
con.Close();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
if (recordShown)
{
con.Open();
currentRow[1] = tbFirstName.Text;
currentRow[2] = tbMiddleName.Text;
currentRow[3] = tbLastName.Text;
currentRow[4] = tbSuffix.Text;
currentRow[5] = tbHomePhone.Text;
currentRow[6] = tbCellPhone.Text;
currentRow[7] = tbOtherPhone.Text;
currentRow[8] = tbStreetAddress.Text;
currentRow[9] = tbCityAndState.Text;
currentRow[10] = tbCountry.Text;
currentRow[11] = tbEmail.Text;
dAdapter.Update(dataset, "Contacts");
con.Close();
}
else
{
MessageBox.Show("Please locate/add a record first.");
}
}
private void btnDelete_Click(object sender, EventArgs e)
{
con.Open();
currentRow.Delete();
dAdapter.Update(dataset, "Contacts");
clearTextBoxes();
recordShown = false;
con.Close();
}
}
}
Thanks!
Here is one explanation but I am not sure if it is exactly what you are seeing:
http://blogs.msdn.com/b/spike/archive/2010/04/07/concurrency-violation-the-updatecommand-affected-0-of-the-expected-1-records.aspx
This might be more on track and if so points to some missing lines that should come after you declare cmdBuilder:
dAdapter.UpdateCommand = cmdBuilder.GetUpdateCommand();
dAdapter.InsertCommand = cmdBuilder.GetInsertCommand();
dAdapter.DeleteCommand = cmdBuilder.GetDeleteCommand();
http://www.codeguru.com/forum/archive/index.php/t-337168.html
Also, you might need to call:
dAdapter.Fill(dataset, "Contacts");
before the con.Close() for all three operations (Insert, Update, and Delete).
On an unrelated note, you could reduce duplicate code by changing the "fillTextBoxes(int row)" method to be just:
private void fillTextBoxes(int row)
{
DataRow dr = dataset.Tables["Contacts"].Rows[row];
fillTextBoxes(dr);
}
A couple things, it looks like you are not passing it back the ID of your identity column when calling update. Wouldn't it need to know the ID when doing an update?
In addition to the comment that srutzky made about the redundant code in fillTextBoxes, you might also consider not referencing your columns by ordinal value and instead reference them by their actual column name. If you were to add a column to your DB, it would break all of your code that is doing things like:
tbLastName.Text = dr.ItemArray.GetValue(3).ToString();
Instead, you might do something like:
tbLastName.Text = dr.ItemArray.GetValue("LastName").ToString();
I don't know offhand if GetValue takes the column name as a parameter, but I'm sure it is something like that.