ExecuteNonQuery returns -1 (incorrectly) - vb.net

I inherited an old VB Website the uses ExecuteNonQuery to modify passwords. In our production environment, sql server 2008 R2, I've had recent reports of broken functionality. It turns out the ExecuteNonQuery is returning -1 when in fact the data is getting updated (a single row). When I copied the data to our dev environment, the rows affected is 1 as expected. We have a different service packs applied (4XXX vs 6XXX) and I wonder if this is the issue? I modified the code to use ExecuteScalar to inspect the RowCount, and this is working. But I shouldn't have to do so. Any insight? I have now idea how long this has been broken.
Here's the original code, that returns -1 erroneously. It is not calling a stored procedure and there are no triggers involved.
Dim cmd As SqlCommand = New SqlCommand("UPDATE UserMaster " & _
" SET Password = #Password, LastPasswordChangedDate = #LastPasswordChangedDate " & _
" WHERE Username = #UserName AND ApplicationName = #ApplicationName ", conn)
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 255).Value = CreateHash(newPwd)
cmd.Parameters.Add("#LastPasswordChangedDate", SqlDbType.DateTime).Value = DateTime.Now
cmd.Parameters.Add("#Username", SqlDbType.VarChar, 255).Value = username.TrimEnd
cmd.Parameters.Add("#ApplicationName", SqlDbType.VarChar, 255).Value = Left(pApplicationName, 1)
Dim rowsAffected As Integer = 0
Try
conn.Open()
rowsAffected = cmd.ExecuteNonQuery()
This code returns a 1 as expected:
Dim cmd As SqlCommand = New SqlCommand("UPDATE UserMaster " & _
" SET Password = #Password, LastPasswordChangedDate = #LastPasswordChangedDate " & _
" WHERE Username = #UserName AND ApplicationName = #ApplicationName ; select ##rowcount", conn)
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 255).Value = CreateHash(newPwd)
cmd.Parameters.Add("#LastPasswordChangedDate", SqlDbType.DateTime).Value = DateTime.Now
cmd.Parameters.Add("#Username", SqlDbType.VarChar, 255).Value = username.TrimEnd
cmd.Parameters.Add("#ApplicationName", SqlDbType.VarChar, 255).Value = Left(pApplicationName, 1)
Dim rowsAffected As Integer = 0
Try
conn.Open()
rowsAffected = CType(cmd.ExecuteScalar(), Integer)

ExceuteNonQuery returns -1 for all stored procedures as per the Msdn documentation.
It will return the updated records' number only in case of a statement.

Related

Avoiding Cross Side Scripting in asp.net

I am currently coding a registration module. Basically, it's a registration module that takes the user info from asp.net site and sends them to the SQL server. I made significant changes but I still have XSS issues when I scan it with acunetix. The registration module works just fine but I wanted to avoid XSS. Because it's clearly vulnerable and it did not pass the acunetix scan.
The last code that I came up with is below. It's a button click event.
Dim connQuery As String = "Data Source=myserver;Initial Catalog=mydatabase;Integrated Security=True"
Dim cs As SqlConnection = New SqlConnection(connQuery)
Dim da As SqlDataAdapter = New SqlDataAdapter()
Dim table As String = "[mydatabase].[dbo].[users]"
Dim query As String = "INSERT INTO " & table & "(passwd, FName, LName, Organization, TelNo, FaxNo, Title, Email, User_type, GroupID, Activated, request_num, FirstLogin, LastLogin, IsLoggedin, IsOutsideInv, WI, study_type) VALUES (#passwd, #FName, #LName, #Organization, #TelNo, #FaxNo, #Title, #Email, #User_type, #GroupID, #Activated, #request_num, #FirstLogin, #LastLogin, #IsLoggedin, #IsOutsideInv, #WI, #study_type)"
Try
da.InsertCommand = New SqlCommand(query, cs)
' da.InsertCommand.Parameters.Add("#passwd", SqlDbType.NVarChar).Value = txtPassword.Text
da.InsertCommand.Parameters.Add("#passwd", SqlDbType.NVarChar).Value = encode(txtPassword.Text)
da.InsertCommand.Parameters.Add("#FName", SqlDbType.NVarChar).Value = txtFirstName.Text
da.InsertCommand.Parameters.Add("#LName", SqlDbType.NVarChar).Value = txtLastName.Text
da.InsertCommand.Parameters.Add("#Organization", SqlDbType.NVarChar).Value = txtOrg.Text
da.InsertCommand.Parameters.Add("#TelNo", SqlDbType.NVarChar).Value = txtPhone.Text
da.InsertCommand.Parameters.Add("#FaxNo", SqlDbType.NVarChar).Value = txtFax.Text
da.InsertCommand.Parameters.Add("#Title", SqlDbType.NVarChar).Value = txtTitle.Text
da.InsertCommand.Parameters.Add("#Email", SqlDbType.NVarChar).Value = txtEmail.Text
da.InsertCommand.Parameters.Add("#User_type", SqlDbType.Int).Value = 0
da.InsertCommand.Parameters.Add("#GroupID", SqlDbType.NVarChar).Value = 0
da.InsertCommand.Parameters.Add("#Activated", SqlDbType.Bit).Value = 0
da.InsertCommand.Parameters.Add("#request_num", SqlDbType.Int).Value = 0
da.InsertCommand.Parameters.Add("#FirstLogin", SqlDbType.DateTime).Value = DateAndTime.Now
da.InsertCommand.Parameters.Add("#LastLogin", SqlDbType.NVarChar).Value = DateAndTime.Now
da.InsertCommand.Parameters.Add("#IsLoggedin", SqlDbType.Bit).Value = 0
da.InsertCommand.Parameters.Add("#IsOutsideInv", SqlDbType.NVarChar).Value = 0
da.InsertCommand.Parameters.Add("#WI", SqlDbType.NVarChar).Value = txtInves.Text
da.InsertCommand.Parameters.Add("#study_type", SqlDbType.NVarChar).Value = 0
cs.Open()
da.InsertCommand.ExecuteNonQuery()
cs.Close()
Catch ex As Exception
Labelmessage.Text = "Error while adding record to the database ==> " & ex.Message.ToString()
Finally
cs.Close()
End Try
What would be the ideal way to pass this scan? I would appreciate any help.

Conversion from string to type Double is not valid

I want to add a value to a field that has value from before.
My code is:
Dim Credits As Integer = Int64.Parse(FinalPay.ToString)
Dim cmd As New SqlCommand("Update Users Set Credit=Credit+" + Credits +
" Where Email ='" + UserEmail + "'", con)
But I get an error that says:
"Conversion from string to double is not valid"
If you use SQL parameters it should work correctly:
Dim cmd As New SqlCommand("UPDATE Users SET Credit = Credit + #Credits Where Email = #Email", con)
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#Credits", .SqlDbType = SqlDbType.Int, .Value = finalPay})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#Email", .SqlDbType = SqlDbType.NVarChar, .Size = 256, .Value = userEmail})
Adjust each parameter type (and size) to match the declarations in the database.
Dim Credits As Integer = Int64.Parse(FinalPay.ToString)
Dim cmd As New SqlCommand("Update Users Set Credit=Credit+" & Credits &
" Where Email ='" & UserEmail & "'", con)
When you want to concat a string in vb you want to use the "&" operator

fetching data from SQL server and print it out using loop

I'm trying to fetch all the data rows in a sql server to print all the values. Here is the code I already tried but it still does not work. Can someone tell me what is wrong here? I'm quite new to vb.net
For i = 1 To 100
Dim testsection As String = e.Item.DataItem("sectionName")
e.Item.Cells(4).Text = strSection & testsection
Next
i dont quite understand how it fetch the data. i juz work as a fresh grad. but they already assign me this advance task. here is the codes in my DBFunction.
Public Function GetUserList(ByVal strUserLogin As String, ByVal strName As String, _
ByVal intCompanyID As Integer, ByVal tblName As String) As DataSet
Dim oConn As SqlConnection = Nothing
Dim SQLStr As String = ""
Dim SubSQL As String = ""
Dim CMD As SqlCommand = Nothing
Dim DS As New DataSet
Dim DA As New SqlDataAdapter
Try
oConn = New SqlConnection(ConnectionString)
oConn.ConnectionString = ConnectionString
oConn.Open()
CMD = oConn.CreateCommand
CMD.CommandType = CommandType.StoredProcedure
SQLStr = "sp_tblUser_Get"
'CMD.Parameters.Add("#CompanyID", SqlDbType.Int).Value = intCompanyID
CMD.Parameters.Add("#LoginID", SqlDbType.VarChar, 50).Value = strUserLogin
CMD.Parameters.Add("#Name", SqlDbType.VarChar, 50).Value = strName
'If strUserLogin <> "" Then
' SubSQL = " AND u.UserLogin = " & SQLS(strUserLogin)
'End If
'If intCompanyID <> 0 Then
' SubSQL = " AND u.CompanyId = " & SQLN(intCompanyID)
'End If
'SQLStr = "select u.ID, u.UserLogin, u.Name, c.CompanyName, u.CreateDate from tblUser u " & _
' " inner join tblCompany c on u.CompanyId = c.ID WHERE u.ID <> 0 " & SubSQL
CMD.CommandText = SQLStr
DA.SelectCommand = CMD
DA.Fill(DS, tblName)
CMD = Nothing
DA = Nothing
oConn.Close()
oConn = Nothing
Catch ex As System.Exception
DS = Nothing
Finally
If Not oConn Is Nothing Then
oConn.Close()
oConn = Nothing
End If
If Not CMD Is Nothing Then
CMD = Nothing
End If
End Try
Return DS
End Function
Basically lines from Dim oConn As SqlConnection = Nothing to DA.SelectCommand = CMD are used to create connection with the database and have steps to call procedure having name sp_tblUser_Get.
Then all the required parameters of this procedure are paased using lines
CMD.Parameters.Add("#LoginID", SqlDbType.VarChar, 50).Value = strUserLogin
CMD.Parameters.Add("#Name", SqlDbType.VarChar, 50).Value = strName
After that using SqlDataAdapter's Fill method data set is filled with the out put.
Dataset DS can contain single DataTable or multiple Datatables which depends on hot Stored procedure is written.
I am assuming it contains single datatable, then if you want to view data then in you can use.
DataTable dt= DS.Tables[0];
This dt Datatablw will contain all data.
To display that data you can use loop like mentioned below.
DataTable dt = DS.Tables[0];
foreach (DataRow dr in dt.Rows)
{
String Name = dr["FirstName"].ToString();
int Age = Convert.ToInt32(dr["Age"]);
}

Execute a stored procedure using VB.NET

This is my procedure
ALTER PROCEDURE sp_addUser
#UserName nvarchar(50),
#Prenom nvarchar(50),
#Nom nvarchar(50),
#Mail nvarchar(50),
#Password char(8),
#Addresse nvarchar(100),
#Ville nvarchar(50),
#Province nvarchar(50),
#PostalCode char(6),
#Pays nvarchar(50),
#AnimalGenre nvarchar(50),
#NomAnimal nvarchar(50),
#Race nvarchar(50)
AS
BEGIN
INSERT INTO Client
VALUES (#UserName,#Prenom,#Nom,#Mail,#Password,#Addresse,#Ville,#Province,#PostalCode,#Pays,#AnimalGenre,#NomAnimal,#Race);
END
I think this ok for the stored Procedure
Now the code to add value in Data Base
Sub sp_addUser()
Dim intRowsAff As Integer
lblErrMsg.Text = ""
lblRecsAff.Text = ""
Dim connectionString As String = WebConfigurationManager.ConnectionStrings("BecsEtMuseauxSQL").ConnectionString
Dim con As SqlConnection = New SqlConnection(connectionString)
Dim cmd As New SqlCommand("sp_addUser", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#UserName", SqlDbType.VarChar, 50).Value = txtUserName.Text
cmd.Parameters.Add("#Prenom", SqlDbType.VarChar, 50).Value = txtPrenom.Text
cmd.Parameters.Add("#Nom", SqlDbType.NVarChar, 50).Value = txtNom.Text
cmd.Parameters.Add("#Mail", SqlDbType.NVarChar, 50).Value = txtMail.Text
cmd.Parameters.Add("#Password", SqlDbType.Char, 8).Value = txtPass.Text
cmd.Parameters.Add("#Addresse", SqlDbType.NVarChar, 100).Value = txtAdresse.Text
cmd.Parameters.Add("#Ville", SqlDbType.NVarChar, 50).Value = txtVille.Text
cmd.Parameters.Add("#Province", SqlDbType.NVarChar, 50).Value = txtProvince.Text
cmd.Parameters.Add("#PostalCode", SqlDbType.Char, 6).Value = txtPostal.Text
cmd.Parameters.Add("#Pays", SqlDbType.NVarChar, 50).Value = txtPays.Text
cmd.Parameters.Add("#AnimalGenre", SqlDbType.NVarChar, 50).Value = rblAnimal.Text
cmd.Parameters.Add("#NomAnimal", SqlDbType.NVarChar, 50).Value = txtAnimal.Text
cmd.Parameters.Add("#Race", SqlDbType.NVarChar, 50).Value = txtRace.Text
Try
cmd.Connection.Open()
intRowsAff = cmd.ExecuteNonQuery()
Catch ex As Exception
lblErrMsg.Text = ex.Message & ex.Source
End Try
lblRecsAff.Text = intRowsAff & " record(s) inserted"
cmd.Connection.Close()
End Sub
After I execute the method VS said that I have to much specified arguments for the procedure sp_addUser
I don't understand why this generate error!
just sync your Sp with code behind method and set parameters as sp.
Dim dt As New DataTable
Dim sqlpr1 As New List(Of SqlParameter)
Dim cmd As New SqlCommand()
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "[sp_ItemPackingList]"
cmd.Parameters.Add("#Date", SqlDbType.DateTime).Value = dateDate.Text.Trim()
cmd.Parameters.Add("#Thk", SqlDbType.VarChar).Value = txtPendQty.Text.Trim()
cmd.Parameters.Add("#Dia", SqlDbType.VarChar).Value = txtPendQty.Text.Trim()
Try
cmd.ExecuteNonQuery()
lblMessage.Text = "Record inserted successfully"
Catch ex As Exception
Throw ex
obj.GetDataTable("[sp_ItemPackingList]", sqlpr1)
End Try
The code and stored procedure you posted appear to be in sync.
That strongly suggests that the stored procedure in the Database is out of sync with what you expect in your code. Suggest you check what you posted is actually the stored procedure in DB.
Also Note: you should not prefix your proc with 'sp_' unless it natually resides in master.
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Try
With con
.ConnectionString = sqlConnectionString
.Open()
End With
With cmd
.CommandText = "UpdateProcedure"
.CommandType = CommandType.StoredProcedure
.Parameters.AddWithValue("CName", txtCName.Text)
.Parameters(0).SqlDbType = SqlDbType.NVarChar
.Parameters.AddWithValue("CAddress",txtCAddress1.Text)
.Parameters(1).SqlDbType = SqlDbType.NVarChar
.Parameters.AddWithValue("CCity", txtCCity)
.Parameters(2).SqlDbType = SqlDbType.NVarChar
.ExecuteNonSqlQuery()
End With
Catch ex As Exception
Finally
cmd.Dispose()
con.Close()
End Try

SQL Server CE query having no effect?

I'm attempting to insert rows into a SQL Server CE database, and it's returning that 1 row is affected, there's no exception, and no syntax error in the query as far as I can see - but it's having no effect, when I look in the table from the Database Explorer.
If I run a query through VS, everything works fine. There's no connection problem as far as I can tell... what am I doing wrong here?
Here's the code, though it probably doesn't make a difference:
Using conn As New SqlCeConnection(My.Settings.DietSafetyCheckerReportsConnectionString)
conn.Open()
Using cmd As SqlCeCommand = conn.CreateCommand()
cmd.CommandText = "INSERT INTO Reports(PatientID, PreparedBy, PreparedFor, WeightInKilos, HeightInMeters, Age, PercentBodyFat, ElbowMeasurementInCentimeters, ReportDate, Gender) " &
"VALUES(#pid, #pby, #pfor, #weight, #height, #age, #bodyfat, #elbow, #rdate, #gender);"
cmd.Parameters.Add("#pid", SqlDbType.NVarChar, 100).Value = Me.PatientID
cmd.Parameters.Add("#pby", SqlDbType.NVarChar, 100).Value = Me.PreparedBy
cmd.Parameters.Add("#pfor", SqlDbType.NVarChar, 100).Value = Me.PreparedFor
cmd.Parameters.Add("#weight", SqlDbType.Float).Value = Me.WeightInKilos
cmd.Parameters.Add("#height", SqlDbType.Float).Value = Me.HeightInMeters
cmd.Parameters.Add("#age", SqlDbType.TinyInt).Value = Me.Age
cmd.Parameters.Add("#bodyfat", SqlDbType.Float, 100).Value = Me.PercentBodyFat
cmd.Parameters.Add("#elbow", SqlDbType.TinyInt, 100).Value = Me.ElbowMeasurementInCentimeters
cmd.Parameters.Add("#rdate", SqlDbType.DateTime).Value = Me.ReportDate
cmd.Parameters.Add("#gender", SqlDbType.TinyInt, 100).Value = Me.Gender
If cmd.ExecuteNonQuery() <> 1 Then Throw New ApplicationException("Failed to insert row into databse.")
End Using
conn.Close()
End Using
(By the way, this also doesn't work:
Using da As New SqlCeDataAdapter("SELECT * FROM Reports", conn)
Dim ds As New DietSafetyCheckerReportsDataSet()
Dim dt As DietSafetyCheckerReportsDataSet.ReportsDataTable
da.Fill(ds)
dt = DirectCast(ds.Tables("Reports"), DietSafetyCheckerReportsDataSet.ReportsDataTable)
Dim dr As DietSafetyCheckerReportsDataSet.ReportsRow = dt.NewReportsRow()
dr.Age = Me.Age
dr.ElbowMeasurementInCentimeters = Me.ElbowMeasurementInCentimeters
dr.Gender = Me.Gender
dr.HeightInMeters = Me.HeightInMeters
dr.PatientID = Me.PatientID
dr.PercentBodyFat = Me.PercentBodyFat
dr.PreparedBy = Me.PreparedBy
dr.PreparedFor = Me.PreparedFor
dr.ReportDate = Me.ReportDate
dr.WeightInKilos = Me.WeightInKilos
dt.Rows.Add(dr)
da.Update(ds)
End Using
)
Look in your bin/debug folder, you probably have more copies of the same database file
My suggestion is that you turned off autocommit mode on server (which is on by default) or on connection settings, so you need to commit your transaction manually. Take a look here for more info.