retrieving row based on input - c#

public void RemoveTask(int index) {
SQL = "DELETE FROM Task where (...) = " +index;
dbConn.Open();
dbCommand = new SqlCeCommand(SQL, dbConn);
dbCommand.ExecuteNonQuery();
dbConn.Close();
}
What i want to do is to delete the record based on the index which specified the row number but I don't know what function or variable should be used ( note the blank ), i try something like rowNum but it does not work.
any help will be appreaciated

It isn't entirely clear what you are trying to do. I think the following code is what you are after - it deletes a row based on the primary key where in this case the name of the primary key column is TaskId (but you can change that based on your table column names).
Note that it also uses parameterised SQL which gives better performance and security.
SQL = "DELETE FROM Task where TaskId = #taskid";
dbConn.Open();
dbCommand = new SqlCeCommand(SQL, dbConn);
dbCommand.Parameters.Add("#taskid", SqlDbType.Int);
dbCommand.Parameters["#taskid"].Value = index;
dbCommand.ExecuteNonQuery();
dbConn.Close();

Related

How to insert data in single column(cell) of new row in c#?

I have an .accdb file with four tables in it
Product_Particulars
Cust_Details
Variable_fields
Permanant_fields
The number of column in the 'Variable_fields' table is not fixed (changed using 'ALTER TABLE' OleDb nonQuery). But it has two fixed columns 'Tranx_ID', 'Tranx_time'.
I want to accomplish something that will enable me to add data in the 'Tranx_ID' Column in a new row from a textBox without caring about other columns in the table (i.e. other cells in that row, in which the 'textBox.Text' is attempted to insert) and save the row with data in only one cell.
N.B.: I am actually using OleDb & I will use the 'Tranx_ID' for Updating that particular row using an OleDbCommand like,
"UPDATE Variable_fields " +
"SET [This column]='" +thistxtBx.Text +
"',[That column]='" +thattxtBx.Text +
"'WHERE ([Tranx_ID]='" +textBox.Text+ "')";
The exception is caused by the fact that one or more of the columns that you don't insert cannot have NULL as value. If you can remove this flag and allow a null value then your INSERT could work or not for other reasons.
Indeed you use a string concatenation to build your query and this is a well known source of bugs or a vector for an hacking tecnique called Sql Injection (I really suggest you to document yourself about this nasty problem)
So your code could be the following
string query = #"UPDATE Variable_fields
SET [This column]= #this,
[That column]=#that
WHERE ([Tranx_ID]=#trans";
using(OleDbConnection con = new OleDbConnection(....constringhere....))
using(OleDbCommand cmd = new OleDbCommand(query, con))
{
con.Open();
cmd.Parameters.Add("#this", OleDbType.VarWChar).Value = thisTextBox.Text;
cmd.Parameters.Add("#that", OleDbType.VarWChar).Value = thatTextBox.Text;
cmd.Parameters.Add("#trans", OleDbType.VarWChar).Value = transTextBox.Text;
int rowsInserted = cmd.ExecuteNonQuery();
if(rowsInserted > 0)
MessageBox.Show("Record added");
else
MessageBox.Show("Record NOT added");
}
Helpful links:
Sql Injection explained
Give me parameterized query or give me death
Using statement

SQL ExecuteNonQuery for Multiple rows

I have a table("Product_Location") with the following columns:
ProductID (PK), LocationID (PK), Quantity
i would like to update the table in the database from rows in a datatable. if row already exists then Update quantity otherwise Insert new row.
i have the following method which update the quantity in the table, if the combination of productID and LocationID exists, it just update otherwise insert new row for that combination. code:
public bool UpdateLocationQuantity(DataSet productLocationData,
SqlTransaction sqlTransaction)
{
try
{
bool result = true;
SqlCommand command = new SqlCommand();
//get the Transaction table which contains rows to update from dataset
DataTable table = productLocationData.Tables["Inventory_Transactions"];
//Create Command Text
string commandText = #" IF Exists (SELECT * FROM Product_Location PL
WHERE ProductID = #ProductID AND LocationID = #LocationID)
UPDATE Product_Location SET Quantity = Quantity + #Quantity
WHERE ProductID = #ProductID AND LocationID = #LocationID
ELSE
INSERT INTO Product_Location (ProductID,LocationID,Quantity)
VALUES(#ProductID,#LocationID,#quantity)";
command = new SqlCommand(commandText, this.CurrentConnection);
command.CommandType = CommandType.Text;
command.Transaction = sqlTransaction;
SqlParameterCollection paramCols = command.Parameters;
//this loop will do the update or insert for all rows in the table
// How can we optimize to only ONE CALL to database?
foreach (DataRow row in table.Rows)
{
paramCols.Clear();
paramCols.AddWithValue("#ProductID",row["ProductID"]);
paramCols.AddWithValue("#LocationID", row["LocationID"]);
paramCols.AddWithValue("#Quantity", row["Quantity"]);
result &= command.ExecuteNonQuery()>= 0;
}
return result;
}
catch
{
throw;
}
}
**My question is how we can optimize the code so only one call to ExecuteNonQuery to update the database instead of having it in a loop? Please note that we are not using StoredProcedure and all should be from C# and SQL Queries or Transactions.
if it was just Update the rows, we could call command.Update with providing the source table and it easily update all the rows without using rows. but since i am using 'IF Exists' then we are forced to use ExecuteNonQuery which is not accepting source table as parameter.
Thank You
Instead of using a ParameterCollection you could do:
command.Parameters.Add(new SqlParameter("#ProductID", ProductData.PRODUCTID_FIELD));
or
command.Parameters.AddWithValue("#ProductID", ProductData.PRODUCTID_FIELD);
and so on. You don't actually have to specify the type.
Then call:
int numOfRowsAffected = command.ExecuteNonQuery();
There is no dataset to be returned, only the number of rows affected, since this is a non-query.
The problem with making a ParameterCollection like you are doing is you then need to set command.Parameters = paramCols; but command.Parameters is Read-Only, so you can't. That is, its read-only as far as assignment goes. You can only add parameters to it through the methods Add and AddWithValue.
for multiple rows , add command in loop
foreach (DataRow row in table.Rows)
{
SqlCommand command = new SqlCommand();
.
.
.
}

Checking for Primary Key assignment

I have a web application that writes to several databases for tracking employee change requests. I am running into a problem with entering in a new employee. They are first written to main Employee database before their access information is written to the other databases with EMP_ID being the primary key. When it goes to write to the other databases EMP_ID has been generated yet so it is getting entered in as 0.
To resolve this I was trying to loop and check the EMP_ID value until a value is generated but I continue to get stuck in a loop because the query returns back that no value was found.
while (int.Parse(empIDChecker) == 0)
{
dbConnection.Open();
validateIDSQLString = "SELECT EMP_ID FROM EMPLOYEE_TABLE WHERE FIRST_NAME = '" + firstNameTextBox.Text.Trim() + "' AND LAST_NAME = '" + lastNameTextBox.Text.Trim() + "'";
SqlCommand updateSQLCmd = new SqlCommand(validateIDSQLString, dbConnection);
SqlDataReader getRecords = updateSQLCmd.ExecuteReader();
try
{
empIDChecker = getRecords["EMP_ID"].ToString();
}
catch
{
empIDChecker = "0";
}
getRecords.Close();
dbConnection.Close();
}
OK, so if your insert sproc looks something like:
sp_InsertEmp
...
INSERT INTO Emp(Name, etc...)
VALUES ('Paul', etc...)
SELECT SCOPE_IDENTITY() AS EMP_ID
GO
And in your code:
SqlCommand insertCmd = new SqlCommand("sp_InsertEmp", dbConnection);
... Add parameters here and set type to StoredProcedure
SqlDataReader dr= insertCmd.ExecuteReader();
int newId;
if (dr.Read())
{
newId = dr.GetInteger(0);
}
you can use
SELECT IDENT_CURRENT(‘tablename’)
This will give you the last inserted auto increment ID of the table, you can use that to insert in other table
Check this link as well http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

How do I store source code lines in SQL Server Database and access it via DataSet

I want to store the following code into the database:
fun(...);
int main()
{
fun(3, 7, -11.2, 0.66);
return 0;
}
fun(...)
{
va_list ptr;
int num;
va_start(ptr, n);
num = va_arg(ptr, int);
printf("%d", num);
}
and then get it back in the dataset and display on a page.
As of now I have successfully stored the questions with varchar(MAX) datatype but when I try to get it in the dataset i get the following error:
Failed To Enable Constraints. One Or More Rows Contain Values Violating Non-null, Unique, Or Foreign-key Constraints.
I am doing this in a ASP.NET web application.
EDIT:
Here is the Table definition of the table I am inserting the data into
The query I am using to insert the data into the table:
con.ConnectionString = constr;
cmd.Connection = con;
cmd.CommandText = "insert into QuesTable values(#D1,#D2,#D3,#D4,#D5,#D6,#D7, NULL)";
cmd.Parameters.Add("#D1", SqlDbType.Int).Value = txtQID.Text;
cmd.Parameters.Add("#D2", SqlDbType.VarChar).Value = txtques.Text;
cmd.Parameters.Add("#D3", SqlDbType.VarChar).Value = txtansa.Text;
cmd.Parameters.Add("#D4", SqlDbType.VarChar).Value = txtansb.Text;
cmd.Parameters.Add("#D5", SqlDbType.VarChar).Value = txtansc.Text;
cmd.Parameters.Add("#D6", SqlDbType.VarChar).Value = txtansd.Text;
cmd.Parameters.Add("#D7", SqlDbType.VarChar).Value = txtcorr.Text;
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
And finally the code by which I am extracting the data from the dataset
DataSet1.QuesTableDataTable dt = new DataSet1.QuesTableDataTable();
DataSet1TableAdapters.QuesTableTableAdapter adp = new DataSet1TableAdapters.QuesTableTableAdapter();
dt = adp.GetData();
DataTable dtUser = dt.Clone();
Hope the information is helpful.
Since I can't see if you've got any other further constraints on the table, it looks like the value you're inserting into the primary key field (Qid) already exists in the table.
If you need to create a new row for every entry regardless, it would probably be easier to change the column Qid to maintain its own Identity. If you need to update an existing value, you'll need to add a separate piece of logic to determine if the primary key value already exists and update or insert accordingly.
That's an error related to either:
A not null field is having a null passed in when you load the data.
A foreign key or unique index check is invalid (for instance, FK value of 9 doesn't exist).
If you fill the dataset, the error that is generated should be retrievable from the dataset.
HTH.

ADO .net 2.0: PrimaryKey not updated after calling DataAdapter.Update()

I came across a problem while updating a typed DataTable that has a primary key column.
At some point in my code I fill DataTables (some of them have primary and foreign key columns) and then I insert the data of all DataTables in one transaction using DataAdapters and Update(). Because the typed DataTables do not allow the PrimaryKey table to be empty I insert some integer values in there. After calling Update() I expected the PK columns to be updated with the database PKs.
public void UpdateMethod(DbTransaction transaction)
{
DbDataAdapter dataAdapter = mDbProviderFactory.CreateDataAdapter();
using (DbCommand insertCommand = CreateCommand())
{
insertCommand.Connection = mDbConnection;
insertCommand.Transaction = transaction;
dataAdapter.InsertCommand = insertCommand;
dataAdapter.Update(dataTable);
}
// not sure if i need to do this:
dataTable.AcceptChanges();
// I would expect that databaseId is now the Id used in the database,
// but it is the original Id which I set while creating the row entry
databaseId = (int)dataTable.Rows[0]["Id"];
}
private DbCommand CreateCommand()
{
// Make command object.
DbCommand cmd = mDbProviderFactory.CreateCommand();
// add command input parameters
DbParameter parameter1 = mDbProviderFactory.CreateParameter();
parameter1.ParameterName = mDatabaseParameterPrefix + "someColumn";
parameter1.SourceColumn = "someColumn";
parameter1.Size = 255;
parameter1.DbType = DbType.String;
// Output parameter
DbParameter idParameter = mDbProviderFactory.CreateParameter();
idParameter.ParameterName = mDatabaseParameterPrefix + "ID";
idParameter.SourceColumn = "ID";
idParameter.Direction = ParameterDirection.InputOutput;
idParameter.DbType = DbType.Int32;
// setup sql command
cmd.Parameters.Add(parameter1);
cmd.Parameters.Add(idParameter)
cmd.CommandText = #"INSERT INTO [SomeTable] ([someColumn], ...) VALUES(#someColumn, ... ) SELECT CAST(SCOPE_IDENTITY() AS int) AS 'ID'";
cmd.UpdatedRowSource = UpdateRowSource.Both;
return cmd;
}
Thanks for any hints!
When you have a primary key set when you fill the datatable, it won't overwrite rows that already exist (however, if it comes across a matching primary key it may or may not update non-key elements depending on what your loadoption is set to)
You would have to clear your datatable first before you fill it I believe.
Solved it. The problem was the SQL statement: Instead of
INSERT INTO [SomeTable] ([someColumn], ...) VALUES(#someColumn, ... ) SELECT CAST(SCOPE_IDENTITY() AS int) AS 'ID'
It must be:
INSERT INTO [SomeTable] ([someColumn], ...) VALUES(#someColumn, ... ) SELECT #ID = SCOPE_IDENTITY()
Otherwise the value of the primary key is not assigned to the output parameter.

Categories