Pre check for data insertion - c#

I want to make a program for value prechecking .a user will give the single input (wbslement no) to UI .I want to insert that record into System . Before inserting into database I want to check It is present in Table or not . if it is present in table then It should not insert record into table if it is not present into database then it should insert .
currently at load time I am fetching all the records from table after that I am trying to insert into System.
in my code it is inserted value any case
CrCon = new SqlConnection(spcallloggin);
CrCon.Open();
CrCmd = new SqlCommand();
CrCmd.Connection = CrCon;
CrCmd.CommandText = "GetOraderNumberDetail";
CrCmd.CommandType = CommandType.StoredProcedure;
sqladpter = new SqlDataAdapter(CrCmd);
ds = new DataSet();
sqladpter.Fill(ds);
for (int count = 0; count < ds.Tables[0].Rows.Count; count++)
{
if (txtwbs.Text == ds.Tables[0].Rows[count][0].ToString())
{
Lbmsg.Visible = true;
Lbmsg.Text = "Data Already Exists !";
count = count + 1;
}
else
{
insetreco(val);
}
}

You could use DataView's RowFilter for querying in-memory tables :
Dataview dv = ds.Tables[0].DefaultView ;
dv.RowFilter="wbslement_no="+number;
if(dv.ToTable().Rows.Count==0)
{
//insert into database
}
else
{
Lbmsg.Visible = true;
Lbmsg.Text = "Data Already Exists !";
}
Or
Instead of two separate calls to the database , you could check for duplicity inside your Stored Procedure.

Just make a "Unique" key constraint on the table itself. MySQL already has an existing construct to handle this, so there's no point doing in your code.

It is better to check it directly in the stored procedure.
IF NOT EXISTS(SELECT * FROM [TABLE] WHERE unique_field = "value of the txtwbs")
BEGIN
INSERT INTO [TABLE]
VALUES (value1, value2, value3,...)
END
Also you can change your code as following:
bool doesExist;
for (int count = 0; count < ds.Tables[0].Rows.Count; count++)
{
if (txtwbs.Text == ds.Tables[0].Rows[count][0].ToString())
{
Lbmsg.Visible = true;
Lbmsg.Text = "Data Already Exists !";
doesExist = true;
break;
}
}
if(!doesExist)
insetreco(val);

Check this :
Make changes according to your need
IF EXISTS (SELECT 1 FROM targetTable AS t
WHERE t.empNo = #yourEmpNo
AND t.project = #yourProject)
BEGIN
--what ever you want to do here
END
ELSE
BEGIN
INSERT INTO yourTable (empno, name, project)
SELECT #empno, #name, #project
END

Related

Joint tables except the empty records (null)

I have two tables (1-N relationship).
(ID,name,surname),
(ID,Job(s),role,society).
In my app I want to merge table1 and table2 (based on the id that binds the two tables) BUT i want to hide the columns that COULD be empty.
Example: (in this case, i don't want to show 'ruolo/grado')
How I wrote the code for this:
CREATE PROCEDURE spEstraiPbyId
#Id int
as
begin
SELECT * from Persone
join Lavori on Persone.Id = #Id and Lavori.IdPersona=#Id
end
PS: I have already seen several similar questions on the internet but no answer was able to satisfy my request or I did not understand correctly. I hope you can help me willingly.
If I understand it correctly, you want to do something like this:
http://sqlfiddle.com/#!18/04141/3
SELECT * from Persone
join Lavori on Persone.Id = Lavori.IdPersona where Lavori.Job is not null
First, use the on joining the keys, and then filter with a where those that are not null :)
Thank you all. Best tip was written by #Serg because to do this i worked on client side, with DataReader and Datatable objs:
DataTable tbl = new DataTable()
SqlCommand cmd = new SqlCommand("spEstraiPById", cnn); //See at the end for spEstraiPById
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("Id",txtNickname.Text);
using (SqlDataReader rdr = cmd.ExecuteReader())
{ //Add columns to the table
tbl.Columns.Add("ID");
tbl.Columns.Add("Nome");
tbl.Columns.Add("Cognome");
tbl.Columns.Add("Residenza");
tbl.Columns.Add("Professione");
tbl.Columns.Add("Ruolo");
tbl.Columns.Add("Società");
while (rdr.Read())
{ //from DB to Table
DataRow drw = tbl.NewRow();
drw["ID"] = rdr["Id"];
drw["Nome"] = rdr["Nome"];
drw["Cognome"] = rdr["Cognome"];
drw["Residenza"] = rdr["Residenza"];
drw["Professione"] = rdr["Professione"];
drw["Ruolo"] = rdr["Ruolo/Grado"];
drw["Società"] = rdr["Società"];
tbl.Rows.Add(drw);
}
foreach (DataRow row in tbl.Rows) //Deleting empty records
{
for (int col = tbl.Columns.Count - 1; col >= 0; col--)
{
if (row.IsNull(col))
{
tbl.Columns.RemoveAt(col);
}
}
// No need to continue if we removed all the columns
if (tbl.Columns.Count == 0)
break;
}
}
gw1.DataSource = tbl;
gw1.DataBind();
cnn.Close();
//=Stored Procedure
CREATE PROCEDURE spEstraiPbyId
#Id int
as
begin
SELECT * from Persone
join Lavori on Persone.Id = #Id and Lavori.IdPersona=#Id
end

C# confirm table row has been deleted from database

I've written a method which will try and delete a row from a db table based on a primary key id. The problem i have is that the try block is always returning "Success" even if a record has already been deleted / or it doesn't exist.
public string delete_visit(int id)
{
string deleteResponse = null;
string cnn = ConfigurationManager.ConnectionStrings[connname].ConnectionString;
using (SqlConnection connection = new SqlConnection(cnn))
{
string SQL = string.Empty;
SQL = "DELETE FROM [" + dbname + "].[dbo].[" + tbname + "] WHERE VisitorNumber = #IDNumber ";
using (SqlCommand command = new SqlCommand(SQL, connection))
{
command.Parameters.Add("#IDNumber", SqlDbType.Int);
command.Parameters["#IDNumber"].Value = id;
try
{
connection.Open();
command.ExecuteNonQuery();
deleteResponse = "Success";
}
catch (Exception ex)
{
deleteResponse = "There was a problem deleting the visit from the database. Error message: " + ex.Message;
}
}
}
return deleteResponse;
}
I want to be able to tell if the row was affected. I can do this in SQL Server Management Studio like so:
DELETE FROM Visits
WHERE VisitorNumber=88;
IF ##ROWCOUNT = 0
PRINT 'Warning: No rows were updated';
So i want to know how do i plug in the ##ROWCOUNT bit into my c# so that i can tell if the row was deleted?
thanks
ExecuteNonQuery() returns an int, indicating how many rows were affected.
So:
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 0)
{
deleteResponse = "No rows affected";
}
The problem is that this number can be influenced based on what the query actually does. Executing triggers or calling stored procedures could mess with the output, changing the affected number of rows. If you really must, then first execute a query where you check that the record with the given ID exists.

C# Code for generating Unique ID for each row inserted into SQL Server 2008 R2

I have written a unique ID generating function that generates a ID every time a new row is inserted into the database. But sometimes it gives same ID for every row. I can't find out what is the problem exactly happening that time. I give you the code for insert into database and code for ID generate. Please review the code and tell me if there is any logical error or not-
// Daily sales report entry codeing…………………………………………………………………………………………………………………
public string GetSalesTeam(SalesTeam st)
{
try
{
SqlConnection con = SqlConnDAC.CreateConn();
SqlCommand cmd = new SqlCommand("Insert into DSR values(#v1,#v2,#v3,#v4,#v5,#v6,#v7,#v8,#v9,#v10,#v11,#v12,#v13,#v14,#v15,#v16)", con);
IDGen.varr = DSR_IDGen(); //Calling id generate function
cmd.Parameters.AddWithValue("#v1", st.Sl_No);
cmd.Parameters.AddWithValue("#v2", st.User_ID);
cmd.Parameters.AddWithValue("#v3", st.Name);
cmd.Parameters.AddWithValue("#v4", st.Branch);
cmd.Parameters.AddWithValue("#v5", st.Desg);
cmd.Parameters.AddWithValue("#v6", st.Visiting_Date);
cmd.Parameters.AddWithValue("#v7", st.Name_Of_Client);
cmd.Parameters.AddWithValue("#v8", st.Address);
cmd.Parameters.AddWithValue("#v9", st.PhNo);
cmd.Parameters.AddWithValue("#v10",Convert.ToInt32(st.QuoteValue));
cmd.Parameters.AddWithValue("#v11", st.Remarks);
cmd.Parameters.AddWithValue("#v12", st.Source);
cmd.Parameters.AddWithValue("#v13",IDGen.varr);
cmd.Parameters.AddWithValue("#v14", st.Month);
cmd.Parameters.AddWithValue("#v15", st.Year);
cmd.Parameters.AddWithValue("#v16",Convert.ToInt32(st.ClosedValue));
// cmd.Parameters.AddWithValue("#v17", st.TypeOfCall);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
return "Success and DSR No.for_ "+st.Name_Of_Client+" = "+IDGen.varr+"";
}
catch (Exception e)
{
return e.ToString();
}
}
//ID generate function………………………………………………………..
public string DSR_IDGen()
{
int i = 0;
string temp;
string var;
var = ("DSR-" + i.ToString()).Trim();
SqlConnection conID = SqlConnDAC.CreateConn();
SqlCommand cmdd = new SqlCommand("select DSR_No from DSR", conID);
conID.Open();
SqlDataReader dr = cmdd.ExecuteReader();
while (dr.Read())
{
temp = (dr[0].ToString()).Trim();
if (var == temp)
{
i = i + 1;
var = ("DSR-" + i.ToString()).Trim();
continue;
}
}
dr.Close();
conID.Close();
return var;
}
// a static variable that holds the ID............................
public class IDGen
{
public static string varr;
}
One word of advice: don't try to make this any more difficult than it is, and don't try to outsmart SQL Server. Why don't you just use the database-provided mechanisms that's already in place for this: an IDENTITY column?
I would recommend you use:
an ID INT IDENTITY(1,1) column to get SQL Server to handle the automatic increment of your numeric value
a computed, persisted column to convert that numeric value to the value you need
So try this:
CREATE TABLE dbo.DSR
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
DsrID AS 'DSR-' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,
.... your other columns here....
)
Now, every time you insert a row into DSR without specifying values for ID or DsrID:
INSERT INTO dbo.DSR(Col1, Col2, ..., ColN)
VALUES (Val1, Val2, ....., ValN)
then SQL Server will automatically and safely increase your ID value, and DsrID will contain values like DSR-0000001, DSR-0000002,...... and so on - automatically, safely, reliably, no duplicates.

Fastest way to update more than 50.000 rows in a mdb database c#

I searched on the net something but nothing really helped me. I want to update, with a list of article, a database, but the way that I've found is really slow.
This is my code:
List<Article> costs = GetIdCosts(); //here there are 70.000 articles
conn = new OleDbConnection(string.Format(MDB_CONNECTION_STRING, PATH, PSW));
conn.Open();
transaction = conn.BeginTransaction();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = transaction;
cmd.CommandText = "UPDATE TABLE_RO SET TABLE_RO.COST = ? WHERE TABLE_RO.ID = ?;";
for (int i = 0; i < costs.Count; i++)
{
double cost = costs[i].Cost;
int id = costs[i].Id;
cmd.Parameters.AddWithValue("data", cost);
cmd.Parameters.AddWithValue("id", id);
if (cmd.ExecuteNonQuery() != 1) throw new Exception();
}
}
transaction.Commit();
But this way take a lot of minutes something like 10 minutes or more. There are another way to speed up this updating ? Thanks.
Try modifying your code to this:
List<Article> costs = GetIdCosts(); //here there are 70.000 articles
// Setup and open the database connection
conn = new OleDbConnection(string.Format(MDB_CONNECTION_STRING, PATH, PSW));
conn.Open();
// Setup a command
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE TABLE_RO SET TABLE_RO.COST = ? WHERE TABLE_RO.ID = ?;";
// Setup the paramaters and prepare the command to be executed
cmd.Parameters.Add("?", OleDbType.Currency, 255);
cmd.Parameters.Add("?", OleDbType.Integer, 8); // Assuming you ID is never longer than 8 digits
cmd.Prepare();
OleDbTransaction transaction = conn.BeginTransaction();
cmd.Transaction = transaction;
// Start the loop
for (int i = 0; i < costs.Count; i++)
{
cmd.Parameters[0].Value = costs[i].Cost;
cmd.Parameters[1].Value = costs[i].Id;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
// handle any exception here
}
}
transaction.Commit();
conn.Close();
The cmd.Prepare method will speed things up since it creates a compiled version of the command on the data source.
Small change option:
Using StringBuilder and string.Format construct one big command text.
var sb = new StringBuilder();
for(....){
sb.AppendLine(string.Format("UPDATE TABLE_RO SET TABLE_RO.COST = '{0}' WHERE TABLE_RO.ID = '{1}';",cost, id));
}
Even faster option:
As in first example construct a sql but this time make it look (in result) like:
-- declaring table variable
declare table #data (id int primary key, cost decimal(10,8))
-- insert union selected variables into the table
insert into #data
select 1121 as id, 10.23 as cost
union select 1122 as id, 58.43 as cost
union select ...
-- update TABLE_RO using update join syntax where inner join data
-- and copy value from column in #data to column in TABLE_RO
update dest
set dest.cost = source.cost
from TABLE_RO dest
inner join #data source on dest.id = source.id
This is the fastest you can get without using bulk inserts.
Performing mass-updates with Ado.net and OleDb is painfully slow. If possible, you could consider performing the update via DAO. Just add the reference to the DAO-Library (COM-Object) and use something like the following code (caution -> untested):
// Import Reference to "Microsoft DAO 3.6 Object Library" (COM)
string TargetDBPath = "insert Path to .mdb file here";
DAO.DBEngine dbEngine = new DAO.DBEngine();
DAO.Database daodb = dbEngine.OpenDatabase(TargetDBPath, false, false, "MS Access;pwd="+"insert your db password here (if you have any)");
DAO.Recordset rs = daodb.OpenRecordset("insert target Table name here", DAO.RecordsetTypeEnum.dbOpenDynaset);
if (rs.RecordCount > 0)
{
rs.MoveFirst();
while (!rs.EOF)
{
// Load id of row
int rowid = rs.Fields["Id"].Value;
// Iterate List to find entry with matching ID
for (int i = 0; i < costs.Count; i++)
{
double cost = costs[i].Cost;
int id = costs[i].Id;
if (rowid == id)
{
// Save changed values
rs.Edit();
rs.Fields["Id"].Value = cost;
rs.Update();
}
}
rs.MoveNext();
}
}
rs.Close();
Note the fact that we are doing a full table scan here. But, unless the total number of records in the table is many orders of magnitude bigger than the number of updated records, it should still outperform the Ado.net approach significantly...

Can I insert the data to a table which columns are unknown in mdb file from c#?

I think I have a weird doubt!!
I have created a table using C#[with a tool not programatically ] in mdb file, then I am inserting the values to that table, what the issue is I don't know how many columns are available in that table, but I wanna insert value from the datagridview..
Spire.DataExport.Access.AccessExport accessExport = new Spire.DataExport.Access.AccessExport();
accessExport.DataSource = Spire.DataExport.Common.ExportSource.DataTable;
accessExport.DataTable = this.dataGridView2.DataSource as System.Data.DataTable;
accessExport.DatabaseName = saveFileDialog1.FileName;
accessExport.TableName = "ExtractedTable";
accessExport.SaveToFile();
//OleDbCommand cmdt = new OleDbCommand("Create Table "+profiletablegrid. ", con);
string strDirectory = saveFileDialog1.FileName;
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strDirectory);
conn.Open();
for (int i = 41; i < dataGridView2.Rows.Count; i++)
{
for (int j = 0; j < dataGridView2.Rows[i].Cells.Count; j++)
{
OleDbCommand cmdd = new OleDbCommand("Insert into sample values(#a,#b,#c,#d)", conn);
cmdd.Parameters.Add("#a", OleDbType.VarChar).Value = dataGridView2.Rows[i].Cells[j].Value.ToString();
cmdd.Parameters.Add("#b", OleDbType.VarChar).Value = dataGridView2.Rows[i].Cells[j].Value.ToString();
cmdd.Parameters.Add("#c", OleDbType.VarChar).Value = dataGridView2.Rows[i].Cells[j].Value.ToString();
cmdd.Parameters.Add("#d", OleDbType.VarChar).Value = dataGridView2.Rows[i].Cells[j].Value.ToString();
cmdd.ExecuteNonQuery();
}
}
So Since I know the columns I am inserting 4 values, but if I don't know how many columns are there, then how can i insert the value...
I can count the datagridview total columns, but how can I insert according to that?
Without knowing column Names or Number of Columns of a table in my experience it's not possible to insert data in to it. How ever you can use this work around to get column names of particular table then insert data into those columns.
The first thing you would do is make sure that no data gets returned:
SELECT TOP 0 your_table.* FROM your_table WHERE 1 = 2;
Now assuming you know how to set up a DataReader you would do the following:
using(var reader = command.ExecuteReader())
{
// This will return false - we don't care, we just want to make sure the schema table is there.
reader.Read();
var table = reader.GetSchemaTable();
foreach (DataColumn column in table.Columns)
{
Console.WriteLine(column.ColumnName);
}
}
Now you have column names so build up your insert statement.
Ok Consider you have n number of columns then your code will look like this.
List<string> colArr=new List<string>();
foreach (DataColumn column in table.Columns)
{
colArr.Add(column.ColumnName);
}
now build your sql in this way.
string colNames="";
string val="";
for (int i = 0; i < colArr.Count; i++)
{
if(i!=colArr.Count-1)
{
colNames+=col+",";
val+="Some Value,";
}
else
{
colNames+=col;
val+="Some Value";
}
}
string sqlQuery="Insert Into your_Table "+colNames+" ("+val+")";
assuming you are using OleDbConnection you can call
DataTable schema = connection.GetSchema("Columns");
to get the schema data of your Database ... in that table you will find each column of each table in the db ...
use that to build you SQL statement at runtime

Categories