I'm working on creating a windows service that will send emails to a customer when they are within a month of having their submission expire. I'm using vb.net in Visual Studios 2008
Because it's a windows service it's very difficult to debug. Trying to narrow down my error I created a "sendDebugEmail" method that sends me an email if it gets to a certain line. The emails never make it past "dr = cmd.ExecuteReader()"
I'm wondering what I am doing wrong. My SQL statement should work fine. I've tested it in my SQL server database.
I've created a dummy_database that I just made in sql server as well. I added an INSERT sql statement for the dummy table i have in there just to see if i could actually access a database. All the table takes in is the line number and time it was sent. When I run my windows service that database updates just fine.
Any help would be appreciated. Thanks
Dim conn As New SqlConnection(connString2)
sendDebugEmail("134")
SQL = "Select email FROM _Customer WHERE custID in (SELECT custID FROM _OnlineCustomer WHERE ExpirationDate <= '6-20-12' AND ExpirationDate >= '6-10-12')"
Dim cmd As New SqlCommand(SQL, conn)
sSubject = "hello"
sBody = "This is test data"
Dim dr As SqlDataReader
sendDebugEmail("143")
Try
dr = cmd.ExecuteReader() // This is were it stops
sendDebugEmail("147")
While dr.Read
sendDebugEmail("152")
Try
LogInfo("Service woke up")
Dim i As Integer = 0
' Prepare e-mail fields
sFrom = "test#gmail.com"
sTo = "test1#gmail.com"
sCc = "test2#gmail.com"
Dim oMailMsg As MailMessage = New MailMessage
oMailMsg.From = sFrom
oMailMsg.To = sTo
oMailMsg.Cc = sCc
' Call a stored procedure to process the current item
' The success message
oMailMsg.Subject = sSubject + "(Success)"
oMailMsg.Body = sBody + "Email has been sent successfully."
' Send the message
If Not (oMailMsg.To = String.Empty) Then
SmtpMail.Send(oMailMsg)
End If
Catch obug As Exception
LogEvent(obug.Message)
Finally
End Try
End While
Catch ex As Exception
Finally
dr.Close()
cmd.Dispose()
conn.Close()
conn.Dispose()
End Try
End Sub
/////////////////////////////////////////////////////////////////////////////////
Problem Solved: I set up my connection but I never opened it.
I needed conn.open()
The thing that helped me most was adding this code into my last catch statement:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
It send me an email of the stackTrace and made it very easy to debug
Are you trapping and swallowing exceptions? If you are, stop. Let exceptions service crash the service: the exception will be logged in the Event log. The only exceptions you should trap are those you can actually recover from (though its valid to catch the exception, log it and rethrow it via throw;).
Have you instrumented your code with log4net (http://logging.apache.org/log4net/), or something similar? You should be, especially for a daemon like a Windows service — how else are you (or operations) going to diagnose problems with the service when the occur (as they will).
Edited to note:
You should be using using statements: all those ADO.Net objects are IDisposable. It makes for cleaner code.
Consider using a SqlDataAdapter to fill a DataTable or DataSet with your results set. The pattern you're using:
read a row from SQL
while read was successful
send an email
read a row from SQL
will ultimately lead to blocking in your database. Talking to a mail server has the potential for a high latency. If the mail server doesn't answer, or you have network congestion, or any of a number of other reasons, you're going to be left hanging until the mail is sent or an exception is thrown due to timeout. And your SQL Query is going to be sitting there with read locks on the table and indices from which you're reading data, blocking people attempting to do updates, inserts or deletes. Your production DBAs will be...vexed. You want to keep your locks moving and get the locks released as quick as you can.
If you are sure about your code (with no exceptions) i think you should check the authentication you are using to connect the SQL server(inside the connection string within the app.config file/inline code of the windows service).
If you are using SQL authentication for this (check the connection string for user name sa and its password) setting the account type of the windows service to LocalService will help you.
If the SQL connection is using windows authentication then setting the account type of the windows service to LocalSystem will help you.
The Account type modification can be done after installation also. For this go to Control panel->Administrative tools->Services->YourService right click and select Propertes->Logon and perform it there. If you are selecting the LocalSystem (windows authentication) you will be asked to enter the login credentials of the account in which the service is running.
In the case of windows authentication in SQL connection the credentials of the account in which the service is running will be taken for SQL connectivity also.
Hope this helps ...
One more suggestion put a sleep statement on your process when it starts so oyu have time to attach to it
Problem Solved: I set up my connection but I never opened it.
I needed conn.open()
The thing that helped me most was adding this code into my last catch statement:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
It send me an email of the stackTrace and made it very easy to debug
Related
please see SQL Management Screen Shot Here
I am getting:
system.data.sqlclient.sqlexception: ' login failed for user 'public_user'.'
when I run my application on VB.NET. Please see the link to check settings on my SQL management studio. This application was running flawlessly previously, however I swapped my HDD to SSD and reinstalled SQL and Visual Studio. Since then I am failing to login as public_user.
I ran a query on SQL as public_user and I am not getting any error message. When I run the application, it does connect to SQL on the app, but it fails to load table1 on datagridview.
I've put tableadapter at the beginning on the mainform, at the end, under sqlconnection1.open, basically any possible places, however I am still getting the same error.
The source code is below, please help me to find the solution:
VB.NET
Microsoft SQL Server 2008 R2
Windows 10 OS
Timer1.Enabled = True
Dim sqlconnection1 As New SqlConnection("server = xxx-xxx-xxx;user id=public_user; password=xxxxxx; Trusted_Connection=True; connection timeout=5")
Dim cmdsql As New SqlCommand
cmdsql.CommandText = "SELECT * FROM [LM2].[dbo].[Table_1]"
cmdsql.CommandType = CommandType.Text
cmdsql.Connection = sqlconnection1
Me.Table_1TableAdapter.Fill(Me.LM2DataSet2.Table_1)
Try
sqlconnection1.Open()
If ConnectionState.Open Then
MsgBox("Connected To SQL")
Else
MsgBox("Failed To Connect SQL")
End If
Catch ex As DataException
MessageBox.Show(ex.Message)
End Try
i've found the solution. When i copied SLN from the old HDD and transferred to SSD, for some reason it automatically deleted the ID and password on ConnectionString settings. I've entered those details on main settings and it is working fine. I had in total 5 SQL Databases which was connecting to my App, and all of them were using same login details for public_user. when i enter credentials it worked for all SQL databases.
I am new to VB.NET and Azure SQL services and I have spent the last 3 days searching for an answer and cannot come up with an answer I can truly understand. Here is my scenario and problem:
I have a VB.NET application where a user will log into their account and have their own set of tables under their own Azure SQL Database. I would like my program to automatically create their database for them (using their own selected name), which would be a database copy of an existing empty Database in Azure.
I can already access the data tables in my master database, but I do not know how to make a copy of it from my program during runtime. When I run my application and it debugs the following snippit of code, I get an exception error saying "You must be logged into the master database" I'm not sure how to resolve that error from popping up as I am using the master admin account in my normal SQL connection string.
Private Sub BtnActivate_Click(sender As Object, e As RoutedEventArgs)
If passwrd1.Password <> passwrd2.Password Then
MsgBox("Password doesn't match Confirm Password.", vbOKOnly)
Else
Dim commandString = "CREATE DATABASE " & dbname.Text & " AS COPY OF DBDEV;"
Using connection As New SqlConnection(My.Settings.DBDEVConnectionString)
Dim command As New SqlCommand(commandString, connection)
Try
connection.Open()
command.ExecuteNonQuery()
MsgBox("DATABASE SETUP. USE " & dbname.Text & "AS DBNAME TO CONNECT TO")
Catch ex As Exception
Throw ex
End Try
End Using
End If
End Sub
Please help, I've been moving nowhere and everything I'm searching for doesn't give me a clear answer to this simple scenario.
After many attempts, I solved the problem: in my connection string, I had the initial catalog default to my database and so I changed it to say "master" (even though I don't have a database named master) and it performed the Database copy for me. Woohoo!
I have developed a .Net application that I want to share to users through shared file in the LAN that is managed through a Domain server. When the server is up and running its fine but when the server is shut down an error comes. I have access to sql server database in that server. When server is shut down it gives a fatal error and application stops. How to detect the error of server being down?
I am connecting to the server through the following code:
Dim sql As String
Dim daCourseMaster As SqlDataAdapter
Try
sqlConn = New SqlConnection(connString)
sqlConn.Open()
sql = " ... "
daCourseMaster = New SqlDataAdapter(sql, sqlConn)
daCourseMaster.Fill(dsDataset, "table")
dvRegister = New DataView
dvRegister = dsDataset.Tables("courseRegisters").DefaultView
dgvCourseRegister.DataSource = dvRegister
Catch ex As Exception
MsgBox(Err.Description)
End Try
Now there might be different reasons why user can not login to the server: either the server name is wrong or user name or password is wrong or thebserver might be shut down! How to differentiate between these reasons to let the user know what might be the reason to failed login?
Use this code before the code that do the sharing (if the code in a Sub):
If Not My.Computer.Network.Ping(" You Server Name or Server IP") Then Exit Sub
or (if the code in a Function):
If Not My.Computer.Network.Ping(" You Server Name or Server IP") Then Exit Function
Lets say, you need to query your database. When you open connection and then when you execute your query, use Try-Catch Block and intercept SqlException. It has different codes, so you can test it for connectivity -related codes
Try
Using conn as new SqlConnection(...)
conn.Open()
....
End Using
Catch (connEx as SqlException)
' sql - related error handling
Catch (ex as Exception)
' here handle all other exception
End Try
this way, you can let user know that connection has lost and "try again later" or something like this
I seem to be receiving random error messages when trying to read queries from a SQLite DB stored on a network drive. On my development machine, I rarely ever get an error, but users are reporting random errors such as:
Unable to open database. File is encrypted or is not a database
Database disk image is malformed
Or it just doesn't return any data.
My code looks like such:
Private Sub LoadStoreCalls()
Dim tmpID As String
Dim QryString As String
Dim SQLconnect As New SQLite.SQLiteConnection()
SQLconnect.ConnectionString = "Data Source=" & SpiceWorksPath & ";New=False;Compress=True;Read Only=True;"
Try
'Open a connection to the database
SQLconnect.Open()
'Get StoreCode
tmpID = Mid(StoreCode, 2) & "-" & StoreName
QryString = "SELECT id, summary, status, c_location, c_store_device FROM tickets WHERE status = 'open' AND c_location = '" & tmpID & "'"
Dim ExQry As New SQLiteCommand(QryString, SQLconnect)
ExQry.CommandType = CommandType.Text
Dim da As New SQLiteDataAdapter(ExQry)
dasSpice.Clear()
da.Fill(dasSpice, "Calls")
SQLconnect.Close()
Catch ex As Exception
If SQLconnect.State = ConnectionState.Open Then SQLconnect.Close()
MsgBox(ex.Message)
End Try
End Sub
The problem is that my application relies on this data being returned to populate additional entries of a datagridview control, and because I cannot replicate this error on my development machine using debug, I cannot find where the fault is occurring.
If the user gets one of these errors, they usually keep trying to run the query and eventually it will work. Or they just exit my application and go back in and then it seems to work for a while. The errors are random and not always from running the same query.
I'm assuming it's due to an issue talking to an SQLite DB on a shared drive, but I can't find any information regarding setting timeouts. I also can't work out how to 'catch' the error because I can't replicate it myself. I have tried adding logging details to the Catch event handler, but it simply just returns me the error message (above) in the logs.
Any help would be greatly appreciated.
Thanks
After many hours of troubleshooting and researching I found that SQLite does not play well with remote connections. Not only was it causing errors in my application, it was also throwing errors in the parent application.
My alternative was to write an application to query the database that ran locally on the SQLite machine. This fixed all of my issues.
For anyone interested...
My application requires a user to log in and allows them to edit a list of things. However, it seems that if the same user always logs in and out and edits the list, this user will run into a "System.Data.SqlClient.SqlException: Timeout expired." error. I've read a comment about it possibly caused by uncommitted transactions. And I do have one going in the application.
I'll provide the code I'm working with and there is an IF statement in there that I was a little iffy about but it seemed like a reasonable thing to do.
I'll just go over what's going on here, there is a list of objects to update or add into the database. New objects created in the application are given an ID of 0 while existing objects have their own ID's generated from the DB. If the user chooses to delete some objects, their IDs are stored in a separate list of Integers. Once the user is ready to save their changes, the two lists are passed into this method. By use of the IF statement, objects with ID of 0 are added (using the Add stored procedure) and those objects with non-zero IDs are updated (using the Update stored procedure). After all this, a FOR loop goes through all the integers in the "removal" list and uses the Delete stored procedure to remove them. A transaction is used for all this.
Public Shared Sub UpdateSomethings(ByVal SomethingList As List(Of Something), ByVal RemovalList As List(Of Integer))
Using DBConnection As New SqlConnection(conn)
DBConnection.Open()
Dim MyTransaction As SqlTransaction
MyTransaction = DBConnection.BeginTransaction()
Try
Using MyCommand As New SqlCommand()
MyCommand.Transaction = MyTransaction
MyCommand.CommandType = CommandType.StoredProcedure
For Each SomethingItem As Something In SomethingList
MyCommand.Connection = DBConnection
If SomethingItem.ID > 0 Then
MyCommand.CommandText = "UpdateSomething"
Else
MyCommand.CommandText = "AddSomething"
End If
MyCommand.Parameters.Clear()
With MyCommand.Parameters
If MyCommand.CommandText = "UpdateSomething" Then
.Add("#id", SqlDbType.Int).Value = SomethingItem.ID
End If
.Add("#stuff", SqlDbType.Varchar).Value = SomethingItem.Stuff
End With
MyCommand.ExecuteNonQuery()
Next
MyCommand.CommandText = "DeleteSomething"
For Each ID As Integer In RemovalList
MyCommand.Parameters.Clear()
With MyCommand.Parameters
.Add("#id", SqlDbType.Int).Value = ID
End With
MyCommand.ExecuteNonQuery()
Next
End Using
MyTransaction.Commit()
Catch ex As Exception
MyTransaction.Rollback()
'Exception handling goes here '
End Try
End Using
End Sub
There are three stored procedures used here as well as some looping so I can see how something can be holding everything up if the list is large enough.
I'm using Visual Studio 2008 to debug and am using SQL Server 2000 for the DB.
Edit: I still seem to be getting this error. I've even removed the whole transaction thing and I still encounter it. At this point, I'm assuming there is some kind of leak happening here. I've tried not using the USING statements and explicitly tell the command and connection to dispose itself but no dice. Memory usage by SQL Server also increases quite a bit if this method is called a lot in a short period of time.
I've read that increasing the CommandTimeout property of the SQLCommand would help. I'm wondering if there are any big disadvantages or consequences from doing so.
I would suggest using the following, that way Dispose will always be called and be Rolledback in every non-committed case.
using (SqlConnection sqlCn = new SqlConnection())
{
using (SqlTransaction myTrans = sqlCn.BeginTransaction())
{
...
myTrans.Commit();
}
}
Also, I don't believe you need to make a new SqlCommand for every execution. Just maintain the same one and update the CommandText and Parameters.
If you have a large number of commands, you may want to build them all before opening the connection. After you start the transaction and open the connection, spin through and execute them.
You probably want to use TransactionScope
Using _tx as New System.Transactions.TransactionScope(<add your own timeout here>)
'Do all your sql work'
If _noErrors Then
_tx.Complete()
End If
End Using
With the transaction scope, you can set a timeout of up to 20 minutes without modifying server settings.
I believe I have managed to solve the problem. I have modified the application so that unnecessary calls to the database are not made (i.e. unchanged objects do not need to be updated again) and increased the CommandTimeout property for the SQLCommand object. So far, no problems.
Big thanks for suggestions too.