Retrieve Messages from SQL Stored Procedure in VB.Net - sql-server

I am working on created a login form for an application I am working on. I have my application set up to properly connect to the database and run stored procedures and queries on the database as well.
However I am unsure how to send messages from the database to my VB.Net Application. Right now I have essentially two methods that execute code for my database:
Public Function ExecuteCMD(ByRef CMD As SqlCommand) As DataTable
Dim DS As New DataSet()
Try
OpenDBConnection()
CMD.Connection = DB_CONNECTION
If CMD.CommandText.Contains(" ") Then
CMD.CommandType = CommandType.Text
Else
CMD.CommandType = CommandType.StoredProcedure
End If
Dim adapter As New SqlDataAdapter(CMD)
adapter.SelectCommand.CommandTimeout = 300
adapter.Fill(DS)
Catch ex As Exception
Throw New Exception("Database Error: " & ex.Message)
Finally
CloseDBConnection()
End Try
Return DS.Tables(0)
End Function
Public Function ExecuteCMDWithReturnValue(ByRef CMD As SqlCommand) As Boolean
Try
OpenDBConnection()
CMD.Connection = DB_CONNECTION
CMD.Parameters.Add("#ret", SqlDbType.Int).Direction = ParameterDirection.ReturnValue
CMD.CommandType = CommandType.StoredProcedure
CMD.ExecuteNonQuery()
Dim result As Object = CMD.Parameters("#ret").Value
Return If(Convert.ToInt32(result) = 1, False, True)
Catch ex As Exception
Throw New Exception("Database Error: " & ex.Message)
Return False
Finally
CloseDBConnection()
End Try
End Function
These functions honestly work fine, but they are horrible for error processing.
For example I'd like to be able to set up my Store Procedure for logging in to the application to return a "Username not found" or "Password incorrect" message so that I can display to my user exactly what the problem is, as opposed to just returning a generic "Login information incorrect" message from only returning true or false on the logging in going through or not.
I unfortunately do not know exactly how to do this on either end. I don't know what to set up on the SQL Server side to have it spit out messages in procedures, and I don't know hot to receive those messages in VB.Net.

You can verify your user right in VB. I don't think it is a good idea to tell the user If the password or user name is wrong (or if both are wrong). If this data is password protected then it should be protected from malicious logins. It would help a hacker to know what was wrong.
Private Function VerifyPassword(pword As String, uname As String) As Boolean
Using cn As New SqlConnection(My.Settings.UsersConnectionString)
Dim cmd As New SqlCommand("Select Count(*) From Users Where UserName = #UserName And UserPassword = #Password;", cn)
cmd.Parameters.Add("#UserName", SqlDbType.VarChar, 100).Value = uname
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 100).Value = pword
Try
cn.Open()
Dim i As Integer = CInt(cmd.ExecuteScalar())
If i > 0 Then Return True
Return False
Catch ex As Exception
Throw
Finally
cn.Close()
cmd.Dispose()
End Try
End Using
End Function
Of course the password is stored hashed with a salt.

Related

Upload Image using VB.Net and SQL Server

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim command As New SqlCommand("insert into rent(Image,Status)values(#Image,#Status)", connection)
Dim ms As New MemoryStream
PictureBox1.Image.Save("ms", PictureBox1.Image.RawFormat)
command.Parameters.Add("#Image", SqlDbType.VarChar).Value = ms.ToArray
command.Parameters.Add("#Status", SqlDbType.VarChar).Value = TextBox5.Text
connection.Open()
If command.ExecuteNonQuery = 1 Then
MessageBox.Show("Successfully uploaded")
Else
MessageBox.Show("Not uploaded")
End If
connection.Close()
End Sub
I'm trying to upload an image into my SQL Server using Visual Studio; everything is working except when I click the upload button, I keep getting the following error:
I tried every possible solution and no luck, I tried enabling the tcp and changing the ip even in SQL Server.
The error you get means that you can't connect to SQL Server.
Make sure your connection string is correct, and you don't have a firewall blocking the connection between the computer that runs the code and the computer that hosts SQL Server.
However, once you sort the connection error, you still have a few problems with your code.
change PictureBox1.Image.Save("ms", PictureBox1.Image.RawFormat)
to PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
to save the image into the memory stream.
Change command.Parameters.Add("#Image", SqlDbType.VarChar).Value = ms.ToArray
to command.Parameters.Add("#Image", SqlDbType.VarBinary).Value = ms.ToArray
because memoryStream.ToArray returns a byte array, not a string.
make sure the Image column in your table is, in fact, VarBinary.
SqlCommand, SqlConnection and MemoryStream all implements the IDisposable interface, therefor you should use all of them as local variable inside the using statement. Your code suggest you are using a class level SqlConnecion instance. That should be changed.
All communication with the database should be inside a try...catch block, since too many things you can't control can go wrong (network disconnected, for instance).
Your code should look more like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim RowsEffected as int = 0
Using Dim connection As NewSqlConnection(ConnectionString
Using Dim command As New SqlCommand("insert into rent(Image,Status)values(#Image,#Status)", connection)
Using Dim ms As New MemoryStream
PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
command.Parameters.Add("#Image", SqlDbType.VarBinary).Value = ms.ToArray
command.Parameters.Add("#Status", SqlDbType.VarChar).Value = TextBox5.Text
Try
connection.Open()
RowsEffected = command.ExecuteNonQuery()
End Try
Catch Exception ex
MessageBox.Show("Failed to upload image:"& VbCrLf & ex.Message)
End Catch
End Using
End Using
End Using
If RowsEffected = 1 Then
MessageBox.Show("Successfully uploaded")
Else
MessageBox.Show("Not uploaded")
End If
End Sub

VB.net SQL Backup with user choosing path

I am trying to figure out how to program a SQL Server backup through a button click on my application, allowing the user to choose the path in which it's saved.
So far I have the following but I am stuck on how to proceed.
Private Sub Backup_Click(sender As Object, e As EventArgs) Handles Backup.Click
Dim sqlconnectionstring As String = "Data Source=ressqlxd023.silver.com\int;Initial Catalog=hw3qwq_c51twed;Integrated Security=True"
Dim conn As New sqlconnection(sqlconnectionstring)
conn.open()
Dim cmd As New sqlcommand
cmd.connection = conn
cmd.ExecuteNonQuery()
conn.close()

Cannot connect project to a SQL Server database

I have a problem while trying to copy my project folder to another hard drive. My project in Visual Studio is defined in h:\ and while run exe file project no any problem but while copy folder project to another hard drive I have a problem to connect the application to SQL Server.
See these screenshots:
http://upload.tehran98.com/img1/f9kio8ssjofg1lhkjdg.jpg
http://upload.tehran98.com/img1/k6ajdb22xhdjrgcn419.jpg
For example in login form and in login button my code is:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim conn As New SqlConnection("Server=.\SQLExpress;AttachDbFilename=" + Environment.CurrentDirectory + "\Database\Automation.mdf;Database=Automation;Trusted_Connection=Yes;")
s2 = "Select count( * ) from Login where UserName = '" & TextBox1.Text & "' and Password = '" & TextBox2.Text & "'"
Dim com As New SqlCommand(s2, conn)
Dim res As Object
conn.Open()
res = com.ExecuteScalar()
conn.Close()
If res = 1 Then
MsgBox("Welcome Dear " + TextBox1.Text, MsgBoxStyle.OkOnly, "Login Successful")
us = TextBox1.Text
If us = "admin" Then
Main.Label4.Text = "ADMINISTRATOR"
Else
Main.Label4.Text = "USER"
us = TextBox1.Text
Main.Button3.Enabled = False
Main.Button5.Enabled = False
Main.Button9.Enabled = False
End If
Main.Show()
Me.Hide()
Else
MsgBox("Invalid User OR Password", MsgBoxStyle.Critical, "Attention Please")
TextBox1.Text = ""
TextBox2.Text = ""
Exit Sub
End If
End Sub
You need to specify where the database is, you can't use Environment.CurrentDirectory. CurrentDirectory uses the path of the current working directory. So either move the database to the same hard drive or change the path to your database.
http://msdn.microsoft.com/en-us/library/system.environment.currentdirectory.aspx

Database Connection Management in a Multi-Thread Service

I made a windows service that listens to a port(using HttpListner) and accepts XML Repuest and once the request is valid it connects to a database (usually on the same pc) and construct the xml response and sends it back.
So far, Everything is great except when the service accepts two or more requests that require retrieving 100+ records, it crashes. First, I was using just one shared connection to the database, it does crashes, then I changed to multiple connections i.e. when you need something from the database create your connection.
I did some troubleshooting using eventlog to get the exceptions, here are some of the exception I got before crashing:
A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
The ConnectionString property has not been initialized.
ExecuteReader requires an open and available Connection. The connection's current state is connecting.
ExecuteReader requires an open and available Connection. The connection's current state is open.
Invalid attempt to call Read when reader is closed.
Here is a sample of the code I am using:
Private Sub StartLisitng()
MyListener.Start()
Dim result As IAsyncResult
result = MyListener.BeginGetContext(New AsyncCallback(AddressOf ListnerCallback), MyListener)
End Sub
Private Sub ListnerCallback(ByVal result As IAsyncResult)
StartLisitng()
If result.IsCompleted Then
ctx = MyListener.EndGetContext(result)
Dim HandleRequestThread As New Thread(AddressOf New HandleRequest(ctx).RequestProcess)
HandleRequestThread.Start()
End If
End Sub
Public Function RemoteConnect(ByVal DNSBranch As String) As Boolean
Dim IsRemoteConnected As Boolean = False
RemoteConnString = "Data Source = " & DNSBranch & ";Initial Catalog=xxxxx;User ID=xxxxx;Password=xxxxx;Connect Timeout=5;MultipleActiveResultSets=True;"
RemoteConn = New SqlConnection(RemoteConnString)
Try
RemoteConn.Open()
Catch ex As Exception
IsRemoteConnected = False
End Try
If RemoteConn.State = 1 Then
IsRemoteConnected = True
Else
IsRemoteConnected = False
End If
Return IsRemoteConnected
End Function
Public Function RemoteExeComd(ByVal DNSBranch As String, ByVal query As String) As DataSet
Dim MyDataSet As New DataSet
RemoteConnect(DNSBranch)
Comd = New SqlCommand(query, RemoteConn)
Adapter = New SqlDataAdapter(Comd)
If query.StartsWith("Se") Or query.StartsWith("se") Or query.StartsWith("SE") Then
If RemoteConn.State = ConnectionState.Open Then
Try
Adapter.Fill(MyDataSet)
Catch ex As Exception
EventLog.WriteEntry("My Service", "Exception: " & ex.Message.ToString)
End Try
End If
Else
Try
Comd.ExecuteNonQuery()
Catch ex As Exception
EventLog.WriteEntry("My Service", "Exception: " & ex.Message.ToString)
End Try
End If
Comd.Dispose()
Adapter.Dispose()
Return MyDataSet
End Function
I do not have any problems with the listner or parsing the request, I know I have the problem on how i interact with the databse.
Any advice, Thanks for you time.

SQL Server pooling Issue

I have written a web application in which I have not allowed connection pooling for this application. I have written sample code as shown below which gets record from my table 20 times and fill in Data set I have close connection at every time.
But if I look in SQL Server Activity monitor it shows me one connection open in sleeping mode.
anyone tell me why this happens?
does this sleeping connection increase if users increase?
If SQL Server pools my connection then why its pooling if I have not allowed pooling for this application? How can I avoid this?
Code to fetch data
Try
Dim i As Integer
For i = 0 To 20
Dim _db As New commonlib.Common.DBManager(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString.ToString())
GridView1.DataSource = _db.ExecuteDataSet(CommandType.Text, "SELECT * FROM BT_AppSetting")
GridView1.DataBind()
Next
Catch ex As Exception
Response.Write(ex.Message.ToString())
ex = Nothing
End Try
DBManager constructor
'CONSTRUCTOR WHICH ACCEPTS THE CONNECTION STRING AS ARGUMENT
Public Sub New(ByVal psConnectionString As String)
'SET NOT ERROR
_bIsError = False
_sErrorMessage = Nothing
_cn = New SqlConnection
_sConnectionString = psConnectionString
_cn.ConnectionString = _sConnectionString
Try
_cn.Open()
Catch ex As Exception
_bIsError = True
_sErrorMessage = ex.ToString
ex = Nothing
End Try
End Sub
ExecuteDataSet Function body
Public Function ExecuteDataSet(ByVal CmdType As CommandType, ByVal CmdText As String, ByVal ParamArray Params As SqlParameter()) As DataSet
Try
Dim cmd As New SqlCommand
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
PrepareCommand(cmd, CmdType, CmdText, Params)
da.Fill(ds)
cmd.Parameters.Clear()
If _cn.State = ConnectionState.Open Then
_cn.Close()
End If
Return ds
Catch ex As Exception
_sErrorMessage = ex.ToString
_bIsError = True
ex = Nothing
Return Nothing
End Try
Please help me.... Waiting for kind reply
1)I THINK sql server does not close the connection right away. That why you see it.
2) Since you are closing the connection you should see only one. Unless your users are running the code at the same time. e.g if it was in a web page and there are 2 users, you will/shoudl see 2 connections.
Also if dont close your connections (just to try) your number of connection will (should :) ) go up.
It is your .net application that pools the connection and not sql server.

Resources