I found the code: schemaTable.Rows(i)!COLUMN_NAME.ToString online, but the columns are out of order. Is there a way to enforce row integrity?
I have columns that have numbers like A1 and A16 (not literally, just as examples) that, when listed, show up in order of A1 A10 A11 ... A16 A2.
UPDATE:
TimG, this should explain what you're asking for, I hope.
Using db As New OleDb.OleDbConnect(constr)
db.Open()
Dim cmd As New OleDbCommand(STATEMENT, db)
Dim schemaTable As DataTable = db.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, New Object() {Nothing, Nothing, table_name, Nothing})
Try
For i = 0 To SchemaTable.Rows.Count - 1
MsgBox(schemaTable.Rows(i)!COLUMN_NAME.ToString)
next i
catch e as exception
end try
end using
This entire list returns out of order in the MsgBox (or any other display method). The columns display in the order in which the strings would if they were alphanumeric instead of by the numbers at the end (i.e. A16 comes before A2) but the actual order is A2 A3 A4 ... A16. I'm not certain how to fix this issue outside of breaking down the strings themselves and looking for numerics in the string, but there must be a way to show the actual order in which they occur.
Yes, it appears that the GetOleDbSchemaTable approach (as outlined in the "Create Sample That Lists Columns in a Table" section of the Microsoft support document here) lists the columns in alphabetical order.
You might be happier with the results of using SELECT * to open an empty OleDbDataReader and then iterating through its fields:
Imports System.Data.OleDb
Module Module1
Sub Main()
Using con As New OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Public\Database1.accdb;"
con.Open()
Using cmd As New OleDbCommand
cmd.Connection = con
cmd.CommandText = "SELECT * FROM aTestTable WHERE False"
Dim rdr As OleDbDataReader = cmd.ExecuteReader()
For i = 0 To rdr.FieldCount - 1
Console.WriteLine(rdr.GetName(i))
Next
End Using
End Using
End Sub
End Module
Related
i have a table that captures the details of Products. I want to be able to generate an Auto ID that contains special characters
I have been able to write code that generates the auto ID and also add a new one. But the issue arises when it gets to the 10th and 11th record.
It seems to be seeing the 9th record as the MAX in the database.
this makes it to throw error that there will be duplicate.
For example, record 9 generates CAT009, record 10 generates CAT0010 but instead to generate record 11 as CAT0011, it seems to keep generating CAT0010 because of the MAX function i used in the SELECT statement.
Sub auto()
Try
Dim cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.StartupPath & "\inventory1.accdb")
cn.Open()
Dim dr As OleDbDataReader
Dim cmddr As New OleDbCommand
cmddr.CommandText = "SELECT MAX(category_id) as max_id FROM tblcategory "
cmddr.Connection = cn
dr = cmddr.ExecuteReader
dr.Read()
If IsDBNull(dr("max_id")) Then
autonumber = "CAT00" & 1
Else
Dim str As String
str = dr.Item("max_id").ToString()
Dim P As Double
Dim N As Double
N = Len(str)
P = N - 5
autonumber = "CAT00" & Convert.ToInt32(str.Substring(5, P))+ 1
End If
cn.Close()
Catch Ex As Exception
MsgBox(Ex.Message)
Console.WriteLine(Ex.Message)
End Try
End Sub
The overall concept is a duplicate of other questions, the key concern being proper formatting of the number with correct zero padding. There are various ways to do this in VB.Net, but the Int32.ToString(String) accepts a format string that can handle zero-padding. It's also unnecessary to calculate the string length, since Substring() has an overload to get all remaining characters to the right.
If IsDBNull(dr("max_id")) Then
autonumber = "CAT001"
Else
Dim str As String
str = dr.Item("max_id").ToString()
autonumber = "CAT" & (Convert.ToInt32(str.Substring(3)) + 1).ToString("000");
End If
If the first two zeros should be static (i.e. always "CAT00"), then it is critical to still format the changing portion with proper padding. Otherwise the text strings will not sort properly and so the numeric order will be ineffective. In that case, you should use something like
If IsDBNull(dr("max_id")) Then
autonumber = "CAT00001" '* NOT CAT001
Else
Dim str As String
str = dr.Item("max_id").ToString()
autonumber = "CAT00" & (Convert.ToInt32(str.Substring(5)) + 1).ToString("000");
End If
Of course in either case, be aware that the number of integer digits limits the range of valid numbers. For example, 3 digits ("000") has a maximum of 999.
A better approach is to use pure integer AutoNumbers in the database: 132 -> "CAT132". Then just format the number for display purposes, and when necessary parse user input text to extract the integer portion: "CAT0089" -> 89. This approach highly simplifies the backend code and leaves the AutoNumber functionality to the database itself... no need to have custom code to generate the numbers.
Can you tell me how to get ages from 0-5 and so on from sql server and input the total in a textbox or label? please click the link for sample
Generate Ages
thank you!
Do you mean something like
Dim sql As String = "SELECT age_column FROM your_table WHERE age_column BETWEEN '0' AND '5'"
'The above line selects the all records where age is between 0-5 (Change the variables)
Dim da As New OleDbDataAdapter(sql, connectionstring)
Dim ds As New DataSet
Dim dt as new DataTable
da.Fill(ds)
dt = ds.Tables(0).Copy()
' Above code stores the results in an iterable table
Dim i As Integer = 0
For Each dr as DataRow in dt.Rows
i = i + 1
Next
TextBox1.Text = i
'i will be the total number of records where age is between 0-5, and display it in a `TextBox`
Your question is, however, very poor, and normally people would not put too much effort into answering it, since you've put no effort in yourself.
I am having an issue where SqlBulkCopy is not copying all of the data in a column over to the destination table. I have verified that the source data (which is a .CSV file) has values in the column in all of the rows, but only the first 40 or so rows in that column are getting copied over.
The destination table's columns are set to NVARCHAR(255) and all of them are allowed to be nullable.
Here is my function to do the bulk copy:
Private Sub loadDataFromCSV(ByVal pathToFile As String, ByVal connString As String, ByVal file As String, ByVal colCount As Integer)
Dim fileLocation As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathToFile & ";Extended Properties='text;HDR=NO;FMT=Delimited(,)';"
Dim qry As String = "select * from " & file
Dim CompData As OleDbDataReader
Using destConnection As SqlConnection = _
New SqlConnection(connString)
destConnection.Open()
Using sourceConnection As New OleDbConnection(fileLocation)
Dim cmdSourceData As New OleDbCommand(qry, sourceConnection)
sourceConnection.Open()
CompData = cmdSourceData.ExecuteReader()
Using bulkCopy As SqlClient.SqlBulkCopy = New SqlClient.SqlBulkCopy(connString)
bulkCopy.DestinationTableName = "dbo.Records"
bulkCopy.BatchSize = 10000
bulkCopy.BulkCopyTimeout = 90
Try
bulkCopy.WriteToServer(CompData)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
CompData.Close()
End Try
End Using
End Using
End Using
End Sub
As far as I can tell, all of the data from the table is making it over into the correct columns, with the exception of the 7th column. In the 7th column, I get the first 40 or so rows of data, and then the rest of the values for the column are NULL.
I've run out of ideas for what could be going wrong, so any help would be greatly appreciated.
Thanks.
My guess would be it is coversion errors. OLEDB will infer the datatype of a column based on the first 8 rows (I think) so if your first rows are:
SomeColumn
----------
1
2
3
4
5
6
7
8
9
apple
This initially looks like an integer column, so this is what it is mapped to, but then when it gets to "apple" it can't convert it to an integer, so returns DbNull.
The solution to this is to add IMEX=1 to your connection string, this means that no implicit conversion will be done, and the OleDbReader will just read exactly what is in the csv.
The downside of this is that you will probably then get conversion errors when trying to call the SqlBulkCopy.WriteToServer(DataReader) method. You may need to create a DataTable in the same format as your database table, and iterate over your OleDbReader doing explicit conversions where necessary, then write this DataTable to the database with SqlBulkCopy.
As a hacky workaround I simply put a character string into each column in the top 8 rows of my csv file. It fools sqlbulkcopy into treating all fields as strings. Then in sql delete the records that contain the character string.
I am writing a program for my lab. Based on a salesordernumer (SO-nr) I need to find the corresponding part number out of a table in access and put it into a variable( Prob a string?). later I need to split the different parts from the partnumber but before that I need to get it out of the MS table. This is de code I use now but I get an error.
Private Sub BtnOphaal_Click(sender As Object, e As EventArgs) Handles BtnOphaal.Click
If conn.State = ConnectionState.Open Then
Dim Sonr As String
Sonr = "SELECT *FROM prodvolg "
Dim SQL As New OleDb.OleDbCommand(Sonr, conn)
Dim DataAdapter As New OleDb.OleDbDataAdapter(SQL)
Dim datatabel As New DataTable("prodvolg")
DataAdapter.Fill(datatabel)
Dim queryString As String = "SELECT [pPart] AS Partnummer FROM [prodvolg] WHERE ([pSonr]='" & txtSOnummer.Text & "')"
Dim command As New OleDbCommand(queryString, conn)
Dim reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
txtppart.Text = (reader.GetString(1))
End While
reader.Close()
End If
End Sub
As you can see I'm just a beginning programmer.
The error is occuring at txtppart.Text = (reader.GetString(1)) the error message:
A first chance exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
Additional information: Index was outside the bounds of the array.
at school I learned programming at ADO system but the future seems to be oledb but I don't understand the OLEdb system good so far. If anyone could help me I would be so happy.
The partnumber is could look like this: "CA-017630-6.35M-1/0-2"
Arrays start at index zero, not one. You have only one field returned by the query
txtppart.Text = (reader.GetString(0))
Also, keep in mind that GetString could fail if your row at index zero contains a null value.
If this is the case I suggest to check for null values with
txtppart.Text = IF(reader.IsDBNull(0), string.Empty, reader.GetString(0))
You are retrieving just one field pPart with your SQL statement, so you'll have just one field on the DataReader. Try with reader.GetString(0), because the arrays starts at index zero
I have a RichTextBox which has only text. How can I get the data (data is tab delimited) into my sql server table ? (I am not forced to use RTB so any other options would do fine as long as the entire process will be quick)
Example of text in RTB:
John 1985 (tab) 01 (tab) 19 (tab) 1.80 (tab) 70
Tony 1988 (tab) 02 (tab) 27 (tab) 1.67 (tab) 55
Table in sql Server called "Users":
Name, Year, Month, Date, Height, Weight
I found this code Dim lines As String() = myRichTextbox.Text.Split(New Char() {"\n"c})
so i just need to get each part of every line into a specific column...
any ideas ? I can't seem to get the data from RTB into SQL SERVER table. And i can't find it online... i will loop this process every 10 minutes so i don't want to save the RTB text into a file and then read from that file to save the data in table...
Once you have parsed the data you can use dynamic SQL or a stored procedure to insert the data into the DB.
SQL server manager can build the INSERT syntax for your table e.g.:
INSERT INTO [OIS].[dbo].[Burn_Type]
([Burn_Type]
,[Record_Create_Date]
,[Last_Update_Date]
,[Burn_Fee])
VALUES
(<Burn_Type, varchar(40),>
,<Record_Create_Date, datetime,>
,<Last_Update_Date, datetime,>
,<Burn_Fee, float,>)
You would need to replace the VALUES with your data then execute the SQL, here is some general code:
Public Function UpdateBySQL(ByVal SQL As String, Optional ByVal UserConnectString As String = "") As Integer
Dim sConStr As String = UserConnectString
If sConStr.Length = 0 Then sConStr = g.OISConnectString
Dim cmd As New Data.SqlClient.SqlCommand ' text commands only
Dim iCnt As Integer
Try
' wouldn't work for transactions
Using con As New SqlConnection(sConStr)
con.Open()
cmd.CommandText = SQL
cmd.Connection = con
iCnt = cmd.ExecuteNonQuery()
con.Close()
End Using
Catch ex As Exception
MsgBox(ex.Message & vbCrLf & vbCrLf & SQL)
End Try
Return iCnt
End Function
For higher security and performance use stored procedures.
You can split on the new line character (chr(10)) to get the rows, and then on each row you can split on tab character (chr(9)) to get the "columns"
Dim rows As String() = source.Split(Chr(10))
Dim columns As String()
For Each line As String In rows
columns = line.Split(Chr(9))
Next