SQL Column Does Not Exist Error - sql

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

Related

Visual Basic Project fails to update Microsoft Access database

I have created a database that holds 3 values, the ID, UserName, and Score. I need to create a new entry to this database when the save button is clicked. My program needs to create a new row with the Username and score provided by the application.
This is my code to update an existing database:
Private Sub ButtonSaveScore_Click(sender As Object, e As EventArgs) Handles ButtonSaveScore.Click
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
dataFile = "F:\Documents\Class Documents\CSC289 - K6A - Programming Capstone Project\Project\Scoreboard.accdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
Using con As New OleDbConnection(connString),
cmd As New OleDbCommand("UPDATE [Scores] SET [UserName] = ?, [Score] = ? WHERE [ID] = ?", con)
con.Open()
cmd.Parameters.Add("#ID", OleDbType.Char).Value = "NEW"
cmd.Parameters.Add("#UserName", OleDbType.Char).Value = playerName
cmd.Parameters.Add("#Score", OleDbType.Char).Value = wins
cmd.ExecuteNonQuery()
End Using
End Sub
I get
oledb exception was unhandled
It highlights cmd.ExecuteNonQuery() and says data criteria mismatch.
Can someone give me advice to get this working?
You have a couple of issues there. Firstly, at least one of your parameters is the wrong data type. Secondly, your parameters are in the wrong order.
The Jet and ACE OLE DB providers only partially support named parameters, in that they allow you to use names so that your code can be clearer but they ignore the names and just use the positions. That means that you need to add the parameters to your OleDbCommand in the same order as they appear in the SQL code. You're not doing that so you have one issue there, although that's not the direct cause of your error message.
Even if those providers did fully support named parameters though, you're not using names in your SQL code. That means that there would be no way to match up parameters by name anyway, so how did you think that adding them in the wrong order wouldn't be an issue?
Given that all three of your parameters are specified as the same data type though, the incorrect order would not cause the error message you're seeing. If that data type was correct, you'd just find that the wrong data was saved to some of the columns, which would be even worse, i.e. appearing to work but not rather than just failing. You need to make sure that you use the correct OleDbType value for the column you're trying to save to. If your ID column in the database is specified to contain 32-bit numbers then you should be using OleDbType.Integer for the corresponding parameters. I'd also suggest using VarChar rather than Char unless your column is specifically fixed-width, which a Text column in Access is unlikely to be and I'm not sure even can be.

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

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!

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

Multiple Database connections within 1 application - VB .NET

This may have been answered but my search hasn't found what I was looking for.
Basically, I am developing an application which allows the user to build a query at design time, i.e. for users with no prerequisite knowledge of SQL
The application thus far allows the user to select which table(s) from the database they wish to start querying (I won't go into the details of the rest for now)
My confusion is this; I already have the connection to the database in a subroutine which obtains the schema information and filters it to display only the available tables within the database, which then compiles the data into a listbox, here is that sub:
Public Sub getSchemaInfo()
Dim ds As New DataSet
Dim dt As New DataTable
Dim con As New OleDbConnection
Dim strDatabaseLocation As String = Application.StartupPath
Dim da As New OleDbDataAdapter
Dim i As Integer
'ds.Tables.Add(dt)
con.ConnectionString = "Provider=microsoft.jet.oledb.4.0; data source = " & strDatabaseLocation & _
"\EmployeeDepartment.mdb"
'clear listbox of any data first
frmAddTable.lbTables.Items.Clear()
'Try catch block used to handle connection errors gracefully
Try
con.Open()
'Accessing methods to obtain schema information
dt = con.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, New Object() _
{Nothing, Nothing, Nothing, "TABLE"})
'loop datatable to store schema information within it
For i = 0 To dt.Rows.Count - 1
'compile lbtables with a list of available tables from the database
frmAddTable.lbTables.Items.Add(dt.Rows(i)!TABLE_NAME.ToString())
Next
Catch ex As Exception
MessageBox.Show(ex.Message.ToString(), "Data Load Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
End Try
con.Close()
As you can see, at the very top is all the information regarding the connection to the database and loading of the information into the dataset.
My question is this; Whenever I need to gain access to the database and any information within it, will I have to perform all the connection process (oledbconnection, etc..)
or is there I way I can create a class for the connection functions and simply reference them whenever I need to connect?
For example, I now am in the process of creating another sub which gathers the columns, based on the tables chosen in the listbox, and displays it back onto the main form in the relevant checklistbox, again, connecting to the database, therefore would I need to perform all of the connection processes?
Any information would be very useful, thank you!
It is a standard approach to separate your DAL ( Data Access Logic ) from your Business Logic. I would definitely create a separate class for connecting to the database and executing the queries that would bring back the results that you can then either Bind to a control or iterate over inside a loop.
You might even want to look into using EF ( Entity Framework ) or my favorite LINQ to SQL to help in following a standard Design Pattern. By using a framework like EF or L2S you can leverage their ability to cache objects and return back strongly typed objects versus loosely typed. Strongly typed objects give you intelisense and are less prone to common mistakes like misspelling a field from a DataTable.

Connect an SQL database to a DataGridView with separate command buttons?

I'm a bit puzzled here. I did a form containing a simple datagridview containing data from an MDB file. The connection was alltogether done by Visual Studios wizard so alot of stuff was created automatically. Then I databinded the textboxes to each column in the database and managed to update the database via my own command buttons such as "Update" with this code:
Me.MainTableBindingSource.EndEdit()
Me.MainTableTableAdapter.Update(Me.DBDataSet.MainTable)
Me.DBDataSet.MainTable.AcceptChanges()
This doesn't seem to work with sql. At this point, I've done everything from scratch in this order, added a datagridview and added a database connection with the wizard when connecting the datagridview to a database. Only this time around I created an SQL connection instead.
And Visual Studio created "MainTableTableAdapter", "DBDataSet", "DBDataSet.MainTable".
The SQL server is something which was installed automatically when installing Visual Studio and it does seem to work after creating the table adapter and dataset if there's data in it. In some time I plan to use an SQL Server on the internet which hosts the dataset. So I want to be able to easily edit the source.
The only thing missing now is how to add a row, delete selected row and editing selected row via my own textboxes. More like a fill-in form. Any ideas to put me in the right direction? I've tried googling it and I've found some stuff, but most of it contains stuff on how to create the datasets and etc. And I'm not sure what Visual Studio has done automatically. And I want to update everything just as easily as I did with these three lines of code when I used a local MDB file.
If it's SQL you can do something like this. Here's an example delete function:
Public Shared Function DeleteStuff(ByVal id As Integer) As Integer
Dim query As String = _
"DELETE FROM tbl_Stuff " & _
"WHERE ID_Stuff = " & id & ";"
Dim connection As SqlConnection = YourDB.GetConnection
Dim deleteCommand As New SqlCommand(query, connection)
Dim rowCount As Integer = 0
Try
connection.Open()
rowCount = deleteCommand.ExecuteNonQuery()
Catch ex As SqlException
Throw ex
Finally
connection.Close()
End Try
Return rowCount
End Function
There may be better ways, but you can always pass in SQL queries.
EDIT: Sorry this is more than three lines of code. ;)