I created the coding for a program to check if table exists in database. But it keeps underlining restrictions in the coding.
Error 23 Value of type 'String' cannot be converted to '1-dimensional array of String'
Can you please tell me what i did wrong and check if the rest of my coding correct.
Here is the coding:
Dim cn As New SqlClient.SqlConnection(SQL_Loader("", My.Settings.SQL_Win_Auth, _
My.Settings.SQL_Username, My.Settings.SQL_Password, My.Settings.SQL_Server_Name, _
My.Settings.SQL_DB_Name))
Dim Cmd As New SqlClient.SqlCommand
Dim Reader As SqlClient.SqlDataReader
Cmd.Connection = cn
cn.Open()
Dim restrictions As String
restrictions = "Pastel_Companies"
Dim dbTbl As DataTable = cn.GetSchema("Pastel_Companies", restrictions)
If dbTbl.Rows.Count = 0 Then
MessageBox.Show("Table Does Not Exist")
Else
MessageBox.Show("Table exists")
End If
Thank you for any help given
The correct syntax to call GetSchema is the following
Dim restrictions As String() = new String() {Nothing, Nothing, "Pastel_Companies"}
Dim dbTbl As DataTable = cn.GetSchema("TABLES", restrictions)
The first parameter is the collection that you want to check for the existence of the object (in your case you want to check the TABLES collection)
The second parameter contains an array of restrictions. This array changes following the collection that you want to search. For the TABLES collection you should apply three restrictions database, owner and tablename.
The restrictions should appear in the exact order expected, and if you haven't a value to specify you pass a null value (Nothing in VB)
The offers a pretty good clue; you're passing a string as the second argument to GetSchema instead of a one-dimensional array of strings.
Try this:
Dim restrictions() as string = { Nothing, Nothing, "Pastel_Companies" }
Dim dbTbl As DataTable = cn.GetSchema("Tables", restrictions)
Related
I'm trying to get the names of all tables of ms access database and store in a array. Is there any way to do that? or modification of this, I copied this code so I DONT KNOW WHAT IS IT FOR
con1.Open()
Dim Restrictions() As String = {Nothing, Nothing, "Table1", Nothing}
Dim CollectionName As String = "Columns"
Dim dt As DataTable = con1.GetSchema(CollectionName, Restrictions)
For Each TableRow As DataRow In dt.Rows
Console.WriteLine(TableRow.Item("COLUMN_NAME").ToString)
Next
con1.Close()
To get all the table's names in your database you should use a restriction with 4 Nothing values and a collection named TABLES.
con1.Open()
' No filter on the returned values
Dim Restrictions() As String = {Nothing, Nothing, Nothing, Nothing}
' Just interested in the TABLES collection
Dim CollectionName As String = "TABLES"
' Get the datatable with informations about the tables in the current db
Dim dt As DataTable = con1.GetSchema(CollectionName, Restrictions)
con.Close()
Now to pass everything back to the calling code in an array of strings you could use
Dim names = dt.Rows.Cast(Of DataRow).Select(Function(x) x("TABLE_NAME")).ToArray()
return names
Can someone please explain to me when the "size" column wont work for comparison but I can replace the ID column in my code and it works perfectly fine. Perhaps my formatting of the access database column for Size isnt correct?
I am basically just trying to see if the key and value in my dictionary match the conditions in the access database and if so to write one text, if not write another. The error I keep getting when I have size in my code is:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll IErrorInfo.GetDescription failed with E_FAIL(0x80004005).
For Each KeyPair In dict
Dim key As String
Dim value As Integer
key = KeyPair.Key
value = KeyPair.Value
Dim sqlQry As String
sqlQry = "SELECT Item, Size FROM [Table] WHERE Item = '" & key & "'AND Size>" & value & " "
Console.WriteLine(sqlQry)
Dim topDecision As String
Dim cmd As OleDbCommand
cmd = New OleDbCommand(sqlQry, myconnection)
Dim myreader As OleDbDataReader
myreader = cmd.ExecuteReader()
If myreader.Read() Then
topDecision = "Order"
Else
topDecision = "Dont"
End If
myreader.Close()
Next
Connections and some other database objects provided by ADO.net use unmanaged code internally. They provide a .Dispose method where they release these resources. It is up to the coder to call the .Dispose method. Fortunately, .net provides Using...End Using blocks that handle this for us. Connections, commands and readers should be declared in the method where they are used so they can be properly closed and disposed.
Don't concatenate strings to build sql queries. Use parameters to avoid sql injection. We only need a single command and a single ParametersCollection. Only the values of the parameters change inside the loop.
A special note for OleDb parameters. The names of the parameters are ignored. The position of the parameter in the sql query should match the order that they are added to the ParametersCollection.
Declare KeyPair As KeyValuePair so you can access .Key and .Value properties.
I used a StringBuilder to collect the messages from your code. A StringBuilder is mutable (changeable) whereas a String is not. If I used a String the compiler would have to throw away a string and create a new one on each iteration. The garbage collector would be kept busy.
I used an interpolated string indicated by the $ before the string. It allows us to insert variables directly into the string if they are surrounded by braces { }.
If you follow this sample, be sure the text box at the end has Multiline = True.
Private Sub OPCode()
Dim sqlQry = "SELECT Item, Size FROM [Table] WHERE Item = #Key AND Size > #Value;"
Dim sb As New StringBuilder
Using cn As New OleDbConnection("Your connection string"),
cmd As New OleDbCommand(sqlQry, cn)
cmd.Parameters.Add("#Key", OleDbType.VarChar, 100)
cmd.Parameters.Add("#Value", OleDbType.Integer)
cn.Open()
For Each KeyPair As KeyValuePair(Of String, Integer) In dict
cmd.Parameters("#Key").Value = KeyPair.Key
cmd.Parameters("#Value").Value = KeyPair.Value
Dim topDecision As String
Using myreader = cmd.ExecuteReader()
If myreader.Read() Then
topDecision = "Order"
Else
topDecision = "Dont Order"
End If
End Using
sb.AppendLine($"{KeyPair.Key} - {topDecision}")
Next
End Using
TextBox1.Text = sb.ToString
End Sub
As the title says I have a MS Access database from where I need to find a specific dataset determined by a String Value. the reason for having to do this is so I can find the value of a single cell in this datase which has to be used as a path to find a certain file. my approach so far is the following:
Dim conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\ExaptLokal.accdb")
Dim cmd As New OleDb.OleDbCommand
Dim dt As New DataTable
Dim da As New OleDb.OleDbDataAdapter
Dim sql As String
sql = "SELECT NC_KEY FROM EXAPT_NC_KOPF_DATEN WHERE NC_PROGRAMM_NAME =" & ProgrammNr.Text.ToString
MsgBox(sql)
conn.Open()
cmd.Connection = conn
cmd.CommandText = sql
da.SelectCommand = cmd
da.Fill(dt)
fullpath = dt.ToString
at the end I would like to have the result from my SQL Query as the value of my "fullpath" variable but so far the da.Fill(dt) row is giving me a hard time saying there is a conflict with the datatype.
Is the datatable even needed in this case or might I be able to skip that step and get the result of the query directly in the fullpath variable?
Thanks to everyone in advance
Edit: Thanks for the help (though not the friendliest but who am I to judge) I finally got it to work with the Execute Scalar method. I would just wish newbies to this website would be greeted a little better lol
have a great day
I moved the connection string to a class level variable so you can use it in other methods.
I separated your data access code from your user interface code passing the value from the text box to a function that returns the path.
I changed your select statement to use parameters. Always use parameters to avoid sql injection and avoid errors.
Use Using...End Using blocks to ensure that your database objects are closed and disposed. This Using block covers both the command and the connection.
You can pass the .CommandText and the .Connection directly to the constructor of the command.
When adding parameters to the parameters collection you provide the parameter name, the datatype form the database, and the size of the field. I had to guess at the type and size so, check your database for the actual values.
Since you are expecting a single value you can use .ExecuteScalar.
Private ConStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\ExaptLokal.accdb"
Private Function GetPath(ProgrammNr As String) As String
Dim fullpath As String
Dim sql = "SELECT NC_KEY FROM EXAPT_NC_KOPF_DATEN WHERE NC_PROGRAMM_NAME = #ProgrmmNr"
Using conn As New OleDb.OleDbConnection(ConStr),
cmd As New OleDb.OleDbCommand(sql, conn)
cmd.Parameters.Add("#ProgrmmmNr", OleDbType.VarChar, 100).Value = ProgrammNr
conn.Open()
fullpath = cmd.ExecuteScalar.ToString
End Using
Return fullpath
End Function
Usage...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fullpath = GetPath(ProgrammNr.Text)
End Sub
I have a SQL table called "Customers". In it is a CustomerNumber field with values like "0001234567", i.e. they are made up of numbers only, but some include leading 0s. So, when I try to run something like
sqlFetch(channel=myconn, sqtable="Customers", stringsAsFactors=FALSE)
it returns my customers table where the CustomerNumber field is numeric (instead of character), and consequently I lose all those leading 0s.
Is there a way I can specify the fieldtype for a column or an alternative solution that won't truncate all my leading 0s?
You can control the types of columns more fully using the as.is argument, which is documented in the Details section of ?sqlFetch as well as at the linked documentation for ?sqlQuery and ?sqlGetResults.
Basically, it is either a vector of logicals or a vector of numeric or character indices specifying which columns to leave untouched. This vector will be recycled as necessary.
(Note that RODBC will clobber columns stored in the database with type.convert even if the C API correctly returns char or varchar as the data type of the column in the database. The maintainer has not responded to any of my 4-5 emails on this issue over the past year, and I have since simply used a forked version of RODBC with the needed one line modification ever since.)
You could try specifying a query string and you could even cast the field if you're still having problems.
Sub Main()
Dim myConn As String = System.Configuration.ConfigurationSettings.AppSettings.Get("ConnStr")
Dim sqlConnection As SqlConnection = New SqlConnection(myConn)
Dim strSQL As String = "select cast(CustomerNumber as varchar(30)) as CustomerNumber_varchar, * from Customers"
Dim myds As DataSet
sqlConnection.Open()
Dim cmd As SqlCommand = New SqlCommand(strSQL, sqlConnection)
cmd.CommandTimeout = 60
Dim myReader As SqlDataReader = cmd.ExecuteReader()
myds = ConvertDataReaderToDataSet(myReader)
myReader.Close()
End Sub
Public Function ConvertDataReaderToDataSet(ByVal reader As SqlDataReader) As DataSet
Dim dataSet As DataSet = New DataSet()
Dim schemaTable As DataTable = reader.GetSchemaTable()
Dim dataTable As DataTable = New DataTable()
Dim intCounter As Integer
For intCounter = 0 To schemaTable.Rows.Count - 1
Dim dataRow As DataRow = schemaTable.Rows(intCounter)
Dim columnName As String = CType(dataRow("ColumnName"), String)
Dim column As DataColumn = New DataColumn(columnName, _
CType(dataRow("DataType"), Type))
dataTable.Columns.Add(column)
Next
dataSet.Tables.Add(dataTable)
While reader.Read()
Dim dataRow As DataRow = dataTable.NewRow()
For intCounter = 0 To reader.FieldCount - 1
dataRow(intCounter) = reader.GetValue(intCounter)
Next
dataTable.Rows.Add(dataRow)
End While
Return dataSet
End Function
I am using VB.Net (Visual Studio 2013) and N-tier architecture to populate a combo box list. My code for the class is as below
Public Shared Function List() As List(Of AppName.BusinessLogic.BLL_RMCodeComboClass)
Dim dbo_RMCodeList As New List(Of AppName.BusinessLogic.BLL_RMCodeComboClass)
Dim connTemp As SqlConnection = AppClass.GetConnection
Dim strSelectSQL As String = "SELECT [RMCode] FROM [dbo].[RMMaster] WHERE [dbo].[RMMaster].[Category] = '" & strRMType & "'"
Dim strCommandSelect As New SqlCommand(strSelectSQL, connTemp)
Try
connTemp.Open()
Dim rdrTemp As SqlDataReader = strCommandSelect.ExecuteReader()
Dim clsdbo_RMCodeList As AppName.BusinessLogic.BLL_RMCodeComboClass
Do While rdrTemp.Read
clsdbo_RMCodeList = New BusinessLogic.BLL_RMCodeComboClass
clsdbo_RMCodeList.RMCode = System.Convert.ToString(rdrTemp("RMCode").ToString)
dbo_RMCodeList.Add(clsdbo_RMCodeList)
Loop
rdrTemp.Close()
Catch ex As SqlException
Throw ex
Finally
connTemp.Close()
End Try
Return dbo_RMCodeList
End Function
My objective is to retrieve or populate the combobox with RMCodes depending upon the type. Hence I have used the strSelectSQL accordingly. Please help me to pass the value of the Category to this function so that it becomes dynamic. The value of the Type is selected from another combo box on the presentation/UI layer and as such the Code field should be populated according to the Category chosen.
Thanks in advance
CL
E.g.
Private Function List(type As String) As List(Of Thing)
'...
Dim command As New SqlCommand("SELECT * FROM MyTable WHERE #Type IS NULL OR Type = #Type")
command.Parameters.Add("#Type",
SqlDbType.NVarChar,
50).Value = If(String.IsNullOrEmpty(type),
CObj(DBNull.Value),
type)
'...
End Function
That makes the filter optional. If you pass in Nothing or an empty String then the SQL parameter is NULL and every record matches, otherwise the result set is filtered by the value you pass in.