How do I create an Azure SQL Database copy during runtime? - sql

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!

Related

How can I allow multiple users to access/edit a microsoft access database?

Now I know right off the bat that Microsoft access isn't the ideal client for multiple users accessing it but it's the only one I've got right now. I have built a small program as a sort of inventory management system. There are currently three users that will be using it regularly and at the same time. One issue I am running into with this is that sometimes the database will not be accessible and will give an error stating that the file is already in use by "so and so" user. The other issue is that I'm getting a similar error every now and then where it states "The database has been placed in a state by user on machine that prevents it from being opened or locked". I am connecting to the database through an ACE OLEDB connection using the line below
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
I have also changed some of the settings in the actual access database such as:
Enable all macros
Add the folder the database is in to the trusted locations list
Confirm that the database is set to open in shared mode by default
I don't know if there is something small I've missed or a setting I need to change but as of yet, the problem is still persisting.
Below is an example of how I am using the database. I am using string based SQL commands but am not too familiar with DataSet/DataTable/etc. items, so I may be doing something incorrectly.
'close connection from any previous session
con.Close()
'clear dataset so as not to append data
ds.Clear()
'Select SQL query that selects ALL records from a table
Dim str As String = "SELECT * FROM " & "[" & table & "]" & ""
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
'use try catch statement to open the connection
Try
con.Open()
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'use try catch statement to add a table (dt) to the dataset (ds) in order to store values
Try
ds.Tables.Add(dt)
Catch ex As Exception
End Try
'create new dataadapter object using the sql string from above and the connection created above
da = New OleDbDataAdapter(str, con)
'create new command builder in order to excecute the SELECT SQL statement using the dataadapter created (da)
'specify prefix and suffix for cb
Dim cb = New OleDbCommandBuilder(da) With {
.QuotePrefix = "[",
.QuoteSuffix = "]"
}
'use try catch statement to fill the datatable (dt) using the dataadapter (da)
Try
da.Fill(dt)
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'set the datasource of the datagridview to the datatable
dgv.DataSource = dt.DefaultView
'close the connection to the database
con.Close()
Go to your Back-End Access DB file. File > Options > Client Settings. For your Use Case No Locks should be fine, but Edited record setting will work as well if you need it
but its [sic] the only one I've got right now
Actually, it's not.
Have a look at SQL Server Compact. It's free, it's small and it handles multiple users with aplomb.
You can add all the references you need using NuGet.

SQL Column Does Not Exist Error

Okay, so basically I asked this little earlier today but we didn't get to the root of the problem and a lot of speculation was clouding the solutions. I have a program that currently needs to check a users inputed 'Gamer-Tag' from RegUserName.Text and compare that with Gamer-Tags stored on the SQL Table PersonsA which is in the Members_Details Database.
When the code is ran I receive the below error;
An unhandled exception of type 'System.ArgumentException' occurred in
System.Data.dll
Additional information: Column 'Gamer_Tag' does not belong to table
PersonsA.
However, Gamer-Tag IS in the Table; It's the second Column in the table. The Server is MS SQL Server and when I use the 'SQL Server Management Studio' I can clearly see the table & columns. From there all SQL Codes in relation to the Gamer_Tag column work flawlessly, so it's definitely in the database.
Here's the code which is called when a button is pressed. This code 'calls' the Function with the error.
Dim dbManager As New DatabaseManager() 'My Class Where The Functions Are
If dbManager.CheckGamerTagisMember(RegUserName.Text) Then
MsgBox("Gamer-Tag is NOT A Member.")
GoTo Ender
Else
MsgBox("Gamer-Tag is A Member.")
GoTo Ender
End If
And here's the Function which contains the Error;
Public Function CheckGamerTagisMember(ByVal gamertag As String) As Boolean
Connection = New SqlConnection("Data Source =" & My.Settings.ServerIP & ";Initial Catalog=Members_Details;Integrated Security=False;User=" & My.Settings.UserName & ";Password=*******;")
Connection.Open()
Dim gamertagDatSet As New DataSet()
usersDataAdapter.FillSchema(gamertagDatSet, SchemaType.Source, "PersonsA")
usersDataAdapter.Fill(gamertagDatSet, "PersonsA")
Dim table As DataTable = gamertagDatSet.Tables("PersonsA")
For i As Integer = 0 To table.Rows.Count - 1
Dim storedgamertag As String = table.Rows(i)("Gamer_Tag").ToString.ToString '<-------- ERROR
If (storedgamertag = gamertag) Then
gamertagDatSet.Dispose()
Connection.Close()
Return True
End If
Next
gamertagDatSet.Dispose()
Connection.Close()
Return False
End Function
What could cause this problem? I've checked obvious spelling and spacing, the firewall's off and the Column is without a doubt there. The function code was adapted from my SQL Login function, which worked without any issues, so I'm puzzled on why this isn't working.
Here's a screenshot from MS SQL Server Management Studio showing the PersonsA Table columns.
It's really getting frustrating now.
Some possible reasons:
Your user has actually been denied access to see the column. This can be accomplished via something as simple as:
DENY SELECT ON dbo.PersonsA(Gamer_Tag) TO your_user;
There is more than one PersonsA table, and the one you are accessing in your code is actually in a different schema than dbo. This is why you should always, always, always specify the schema when creating or referencing objects. Always. Read this post for more info.
Your code is connecting to a different server, a different database, or a different copy of the same database than Management Studio. (The latter can happen when using SQL Express and the User Instance/AttachDbFileName settings, which I can see that your code is not using, but I don't know if you are connecting to a user instance from Management Studio.)

Errors With SQLite and VB.net when reading database

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...

Unable to execute SQL command in windows service

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

No Access to an mdb database file after copying the file

I have the following code where I make an copy of my database that I use. the code executes 100% but the problem I have is I'm not able to access my database afterward.I get a "Cannot start your application. The workgroup information file is missing or opened exclusively by another user." and so if I restart the application it all works fine again.
I'm certain the reason is because I can only access that database using a specific account name and password which is not account I'm logged in with.
What i want to try is to default that database mdb to the point where no user is accessing it, or to reassign the the only account name that can access it to that database mdb.
Any ideas, will be enormously appreciated? I've tried playing around with file security but had no luck.
Private Sub cmdBackup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBackup.Click
BackupDialogDB.DefaultExt = ".mdb"
BackupDialogDB.InitialDirectory = "c:\"
'SaveFileDialog1.ShowDialog()
If BackupDialogDB.ShowDialog() = Windows.Forms.DialogResult.OK Then
Try
Dim sDBFile As String = Application.StartupPath + "\VFMS_DB.mdb"
Dim sBackUpFile As String = BackupDialogDB.FileName
'First check the file u want to compact exists or not
If File.Exists(sDBFile) Then
If Not File.Exists(sBackUpFile) Then
File.Copy(sDBFile, sBackUpFile)
Else
File.Delete(sBackUpFile)
File.Copy(sDBFile, sBackUpFile)
End If
MessageBox.Show("The database was successfully backedup to: " + sBackUpFile , "Database Backedup", MessageBoxButtons.OK, MessageBoxIcon.Information)
sDBFile = ""
Else
MessageBox.Show("There is no database to backup. Please restore from a backup", "Database Backup Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Sub
You should also copy and/or restore the workgroup information file.
Do you have write permission in the target directory? Access needs to create a .ldb file along side the .mdb.
Otherwise, you can try some of the stuff here:
http://www.xlinesoft.com/asprunnerpro/docs/error_the_microsoft_jet_database_engine_cannot%20open%20the%20file%20(unknown).htm
Was the Database open when you copied it? Access creates lock files, *.ldb in the same directory the database is in, you might want to check for that file before you copy the database.