简体   繁体   中英

ADODB RecordSet to String() in VB.NET

I found this post which could help me in my project:

ADODB RecordSet to string variable VBA

I want to adapt it to VB.NET instead of VBA, but it does not work.

My goal is to create a String() using SQL. To give you an idea how the string would look like if hard coded, this is how we do it:

Public Sub New()
InitializeComponent()
strValue = New String() {"10051", "65658", "25689" etc... }
End Sub



**'My actual code is as follows:**

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) 
Handles MyBase.Load

Dim Connection1 As New ADODB.Connection
Dim Connection1 As New ADODB.Connection
Dim RecordSet1 As New ADODB.Recordset
Dim SqlQuery1 As String, ConnectionString1 As String
Dim strValue As String()

SqlQuery1 = "Select ItemCode From OITM"
ConnectionString1 = "Driver=SQL Server;Server=Myserver; Database=MyDbase; 
User Id = sa; Password= 12345"
Connection1.Open(ConnectionString1)
RecordSet1 = New ADODB.Recordset
RecordSet1.Open(SqlQuery1, Connection1)
strValue = TryCast(RecordSet1.Fields("ItemCode").Value, String())

Do While RecordSet1.EOF = False
strValue = TryCast(RecordSet1.Fields("ItemCode").Value, String())

MsgBox(strValue)
RecordSet1.MoveNext()
Loop

I expect the MsbBox to show the ItemCode at each looping, and building up the whole (very long) string. But it shows blank.

I read that probably EOF does not work in VB .NET.

What must I do?

I see some problems:

First of all you are casting the value you get from the recordset to a String Array. Why? You shouldn't do it, try setting the value directly like this:

strValue = RecordSet1.Fields("ItemCode").Value  

Second, you are not concatenating the string. Use "+" or "&" to concatenate what are you reading from each row like this:

Do While RecordSet1.EOF = False
    strValue = strValue + RecordSet1.Fields("ItemCode").Value

   MsgBox(strValue)
   RecordSet1.MoveNext()
Loop

But you need an Array for your needs. So you can use a list and then the toArray Method:

Dim strValues As String()
Dim strList As List(Of String) = New List(Of String)()

Do While RecordSet1.EOF = False
    strList.Add(RecordSet1.Fields("ItemCode").Value)
    RecordSet1.MoveNext()
Loop

strValues = strList.ToArray()

Now strValues is your Array Of String read from a SQL db.

I expect the MsbBox to show the ItemCode at each looping, and building up the whole (very long) string

That's just not how it works. Each time through the loop, you have one item . Nothing in the code accumulates the values from each iteration. Attempting to cast as an array, even if it would work (which it doesn't) would still only give you a new array instance on each iteration with just that one item. And again, even this much doesn't happen. You can't just cast a single item as an array.

More than this, .Net uses real arrays, not the array-like collections you see in other languages now. .Net has those collections, too, but it doesn't try to pretend they are arrays. One of the key attributes of a real array is a fixed size . You must know the number of elements in the array when you first allocate it. Even ReDim Preserve relies on this, effectively allocating a whole new array and copying all the elements every time you use it. This means it's really strange to expect casting an item to an array variable will concatenate to the array. It sounds like you may want a List(Of String) instead of an array.

If other parts of your program expect an array, you will want to change them to use the List(Of String) instead. Basic arrays are not used as often any more in .Net, mostly replaced with generic List(Of T) types. And whenever possible, make your method parameters ask for IEnumerable(Of T) instead of T() or List(Of T) . When you use IEnumerable(Of T) , both arrays and lists can be passed as arguments.

Another issue is using an array with MsgBox() . The message box is not smart enough to know what to do with an array. You end up falling back to the System.Object.ToString() overload, which just returns the type name. So even if everything else worked (which it won't), the best you could hope to so see is the text System.Array .

Finally, don't use RecordSet in VB.Net

The old ADO library only exists for backwards compatibility when porting code forward. You shouldn't use it in new development. Use the newer ADO.Net API instead.

Try this:

'At the very top of the file:
Imports System.Data.SqlClient
Imports System.Collections.Generic
Imports System.Text

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) 
    Handles MyBase.Load

    'I know this is just a sample, but DON'T USE THE SA ACCOUNT!
    Dim ConnectionString As String = "Server=Myserver;Database=MyDbase;User Id=sa;Password=12345"    
    Dim Sql As String = "Select ItemCode From OITM"

    Dim result As New List(Of String) 'The "array" (really an array-like collection)
    Dim message As New StringBuilder() 'For building up the string

    Using connection As New SqlConnection(ConnectionString), _
          command As New SqlCommand(sql, connection)

        connection.Open()
        Using reader As SqlDataReader = command.ExecuteReader()
            Dim delimiter As String = ""
            While reader.Read()
               Dim itemCode As String = reader("ItemCode").ToString()
               result.Add(itemCode)
               message.Append(delimiter).Append(itemCode)
               MessageBox.Show(message.ToString())
               delimiter = ","
            End While
        End Using
    End Using
End Sub

Another option is to create a DataTable:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) 
    Handles MyBase.Load

    'I know this is just a sample, but DON'T USE THE SA ACCOUNT!
    Dim ConnectionString As String = "Server=Myserver;Database=MyDbase;User Id=sa;Password=12345"    
    Dim Sql As String = "Select ItemCode From OITM"
    Dim result As New DataSet()

    Using connection As New SqlConnection(ConnectionString), _
          command As New SqlCommand(sql, connection), _
          adapter As New SqlDataAdapter(command)

        adapter.Fill(result)
    End Using
End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM