While clicking on add button data is saved in database but after 2-3 times refresh data in database there 2-4 copies of same data is shown.
How to get to fix this?
String cs = ConfigurationManager.ConnectionStrings["MyDBConnectionString1"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("Insert into tblBrands values('" + txtBrandName.Text + "')", con);
con.Open();
cmd.ExecuteNonQuery();
txtBrandName.Text = string.Empty;
}
If you are trying to solve in SQL (assuming from your tags) you could check before inserting using:
if not exists (select * from tblBrands where ...)
Build your where clause based on your criteria - what would you consider duplicate entry
More info on exists in Microsoft Docs
Related
I am using sql server with my VB.NET application where in multiple instance of the application is run from different server (CITRIX). I am sorting and picking up one individual Row for processing and immediately marking that row as picked in a column so that other instance doesn't pick up the same row and waste time. The issue is, in between picking up the row and updating as picked, another instance of the application is picking up the row. I have been suggested for using with DB Lock but the concept is not that much clear to me like whether it will solve my problem, whether I need admin right to use it (I do not have admin right in client DB) etc. Below is the code snippet I have used.
Dim MyConnection As SqlConnection
Try
MyConnection = New SqlConnection(connString)
MyConnection.Open()
Dim tableName As String = myTableName
Dim sqlQuery As String = "Select Top 1 * from " + tableName + " where "<some condition>
Dim MyCommand As SqlDataAdapter = New SqlDataAdapter(sqlQuery, MyConnection)
Dim DS as DataSet = New DataSet
MyCommand.Fill(DS, tableName)
If DS.Tables(0).Rows.Count >= 1 Then
sqlQuery = "UPDATE " + tableName + " SET Fld = #fld where Cond1= '" + DS.Tables(0).Rows(0).Item("Cond1").ToString + "'"
Dim cmd As New Data.SqlClient.SqlCommand(sqlQuery)
cmd.CommandType = CommandType.Text
cmd.Parameters.Add("#fld", Data.SqlDbType.VarChar).Value = "Picked"
Try
cmd.Connection = MyConnection
cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End If
Catch ex As Exception
MsgBox(ex.ToString)
Finally
MyConnection.Close()
End Try
I want it to make in such way that if an instance picks up a row, until it finishes updating the row, the row will not be visible to other instance with same query on the table, but other instance will continue to work with the other rows at the same time.
Two options I see:
Change your SELECT and UPDATE queries to a single UPDATE query. I didn't see where your SELECT was buying you anything.
If the SELECT is truly needed, then use a stored procedure on the database to handle the SELECT and the UPDATE on the database server side. You can lock the row during the transaction. See: Transaction Locking and Row Versioning Guide
Note that in general you should try to move your database queries to stored procedures. Not only does this reduce the amount of network traffic moving datasets back and forth, it increases the reliability, separates your database code from the UI, allows updates to the procedures without having to push new versions of the client application out and also avoids SQL injection.
I had confusion with my code:
Dim sqladapter As SqlDataAdapter = New SqlDataAdapter()
Dim sqlcmd As SqlCommand = New SqlCommand()
sqlcmd = New SqlCommand("SELECT login, pass from Table1 where login=" & login.Text & "and pass='" & password.Text.ToString() & "';", connect)
Dim dr As SqlDataReader = sqlcmd.ExecuteReader()
Dim dt As DataTable = New DataTable()
dt.Load(dr)
If (dt.Rows.Count = 1) Then
'Display welcome page or do some action here.
Now, my question is, is there any other way of doing Rows.Count==1 . I'm feeling that it is very wrong and makes no sense at.
How do you verify from database that a user has only one valid record in table other than counting rows.
Thanks in Advance :)
(Please ask me before reporting question)
You have two problems, one is called Sql Injection and you have already numerous links that explain why is really bad. Another one is the plain text password stored in your database. This is a big security concern because everyone that has the possibility to look at your database could see the passwords of your users. (The gravity of this, of course, is linked to the nature of your application but cannot be downplayed) See this link for an answer on how to hash a string (a password) and get its encrypted version to store in the database instead of the plain text.
Finally the code you use could be changed to avoid both the SqlDataAdapter and the DataTable.
Just use an ExecuteScalar against an IF EXIST query that return just 1 if the user/password exists or zero if not
Dim cmdText = "IF EXISTS(SELECT 1 FROM Table1 WHERE login = #log AND pass = #pwd) " & _
"SELECT 1 ELSE SELECT 0"
using connect = new SqlConnection(connectionstring)
using sqlcmd = New SqlCommand(cmdText, connect)
connect.Open()
sqlcmd.Parameters.AddWithValue("#log", login.Text)
sqlcmd.Parameters.AddWithValue("#pwd", password.Text) ' <- Subst with a call to an hash function
Dim exists = Convert.ToInt32(sqlcmd.ExecuteScalar())
if exists = 1 Then
'Display welcome page or do some action
else
end if
End Using
End Using
There is only one way to answer to the question and its to count rows. The different solution would be to count them in database. For example you could write stored procedure that takes username and password and returns boolean this way you would drag less data.
As a side note there is potential sql injection in your code. You should not store clear password in database. You should return the whole row and match hash of the password from database to the hash of the paasword that you get from UI.
I have two update sql statements for two SqlCommand object to update one DataTable with DataSet object to One Source Table. When I click on update button that's update only the first one and the second SqlCommand Object doesn't work. What's it? DataTable didn't support two Command object at one time? I write as follow:
Dim conxMain As New SqlConnection("Data Source=SERVER;Initial Catalog=DBTest;Persist Security Info=True;User ID=usr;Password=pwd")
Dim dadStockInfo As New SqlDataAdapter
Dim dsStockInfo As New DataSet
Dim transStockInfo As SqlTransaction = Nothing
Try
conxMain.Open()
transStockInfo = conxMain.BeginTransaction()
dadStockInfo.SelectCommand = New SqlCommand("SELECT * FROM Stock", conxMain, transStockInfo)
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(dadStockInfo)
dadStockInfo.FillSchema(dsStockInfo, SchemaType.Source, "Stock")
dadPurchaseInfo.Fill(dsPurchaseInfo, "Stock")
Dim cmdStockUpdateCmd As SqlCommand = Nothing
cmdStockUpdateCmd = New SqlCommand("UPDATE Stock SET StockCode= 'TestCode' WHERE StockID = 4", conxMain, transStockInfo)
dsStockInfo.Tables("Stock").Columns("StockID").ReadOnly = False
dadStockInfo.UpdateCommand = cmdStockUpdateCmd
//dadStockInfo.Update(dsStockInfo, "Stock") [I have already tried this but did not work]
Dim cmdStockUpdateCmd1 As SqlCommand = Nothing
cmdStockUpdateCmd1 = New SqlCommand("UPDATE Stock SET StockCode= 'Test-Code2' WHERE StockID = 1", conxMain, transPurchaseInfo)
dadStockInfo.UpdateCommand = cmdStockUpdateCmd1
dadStockInfo.Update(dsStockInfo, "Stock")
transStockInfo.Commit()
Can't I use like above? please point me out !
Hello ! Help me! F1 :)
The way you use it you shouln't need the dataadapters and datasets...
You just execute 2 update statements.
You can just do
cmdStockUpdateCmd1 = New SqlCommand("UPDATE Stock SET StockCode= 'Test-Code2' WHERE StockID = 1", conxMain, transPurchaseInfo)
cmdStockUpdateCmd1.ExecuteNonQuery();
Datasets and dataadapters are for getting data to the client.
Changing data on the client side and then sending the modifications to the server.
You are making your changes directly on the server with SQL.
hey guys i want to fetch 3 tables in 1 single ado.net call from my ms access database, however i get an error when i am trying to do that
when i change my sql query to just fetch 1 table, my code works fine
can anyone let me know how to achieve this with ms access? because i have been doing this with sql server since ages without any problems. perhaps access does not support multiple result sets? i have not worked much with access. please help. below is my code for reference:
System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DatabaseFile.mdb;Persist Security Info=True");
System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM Table1; SELECT * FROM Table2; SELECT * FROM Table3;", con);
DataSet ds = new DataSet();
da.Fill(ds);
UPDATE: guys this does not look possible. so i had to write really stupid code to get what i wanted, complete waste of computing resources:
DataSet ds = new DataSet();
ds.Tables.Add(new DataTable("Table1"));
ds.Tables.Add(new DataTable("Table2"));
ds.Tables.Add(new DataTable("Table3"));
System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DatabaseFile.mdb;Persist Security Info=True");
System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM Table1;", con);
da.Fill(ds, "Table1");
da.SelectCommand.CommandText = "SELECT * FROM Table2;";
da.Fill(ds, "Table2");
da.SelectCommand.CommandText = "SELECT * FROM Table3;";
da.Fill(ds, "Table3");
as far as I know, if your data reside inside the Access mdb, you cannot have multiple data sets. If instead you use Access to connect to an external data source, you could use pass-through queries and do that, but I do not think this is your case. (see http://support.microsoft.com/kb/126992)
Is it possible (in Vb.Net 2005), without manually parsing the dataset table properties, to create the table and add it to the database?
We have old versions of our program on some machines, which obviously has our old database, and we are looking for a way to detect if there is a missing table and then generate the table based on the current status of the table in the dataset. We were re-scripting the table every time we released a new version (if new columns were added) but we would like to avoid this step if possible.
See this MSDN Forum Post: Creating a new Table in SQL Server from ADO.net DataTable.
Here the poster seems to be trying to do the same thing as you, and provides code that generates a Create Table statement using the schema contained in a DataTable.
Assuming this works as it should, you could then take that code, and submit it to the database through SqlCommand.ExecuteNonQuery() in order to create your table.
Here is the code:
SqlConnection con = new SqlConnection("Data Source=.;uid=sa;pwd=sa123;database=Example1");
con.Open();
string sql = "Create Table abcd (";
foreach (DataColumn column in dt.Columns)
{
sql += "[" + column.ColumnName + "] " + "nvarchar(50)" + ",";
}
sql = sql.TrimEnd(new char[] { ',' }) + ")";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
using (var adapter = new SqlDataAdapter("SELECT * FROM abcd", con))
using(var builder = new SqlCommandBuilder(adapter))
{
adapter.InsertCommand = builder.GetInsertCommand();
adapter.Update(dt);
}
con.Close();
I hope you got the problem solved.
Here dt is the name of the DataTable.
Alternatively you can replace:
adapter.update(dt);
with
//if you have a DataSet
adapter.Update(ds.Tables[0]);