Как назначить строковую переменную набору данных?

#sql-server #vb.net

Вопрос:

Я читаю строки из файла, проверяю первую строку, а затем мне нужно записать следующие строки файла в таблицу под названием «Тестовая таблица» с помощью метода, который работает с набором данных. Это говорит мне, что я не могу вставить строковый тип в набор данных.

 Dim myStream As Stream = Nothing
    Dim openFileDialog1 As New OpenFileDialog()

    openFileDialog1.InitialDirectory = "Z:FitalogItaliaKMasterSPEKM"   'ATTENZIONE CAMBIARE IN "C:"
    openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
    openFileDialog1.FilterIndex = 2
    openFileDialog1.RestoreDirectory = True


    If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
        Try
            myStream = openFileDialog1.OpenFile()
            If (myStream IsNot Nothing) Then
                Dim objReader As New StreamReader(openFileDialog1.FileName)
                Dim ControlLine As String = ""
                Dim sLine As String = ""
                Dim arrText As New ArrayList()
                ControlLine = objReader.ReadLine
                If (ControlLine.Contains("H06") And ControlLine.Contains("SPEKM")) Then
                    sLine = objReader.ReadLine
                    Dim indice As Integer = 0
                    Do

                        If Not sLine Is Nothing Then
                            arrText.Add(sLine)
                            DB_SQL.SetDBfromDataset("INSERT INTO TestTable (riga) VALUES ("   arrText.Item(indice)   ");", "TestTable")
                            indice =  1
                        End If

                    Loop Until objReader.ReadLine.Count - 1
                End If
                objReader.Close()


            End If
        Catch Ex As Exception
            MessageBox.Show(Ex.Message)
        Finally
            ' Check this again, since we need to make sure we didn't throw an exception on open.
            If (myStream IsNot Nothing) Then
                myStream.Close()
            End If
        End Try
    End If
 

ОБНОВЛЕНИЕ Я ДОБАВИЛ ФУНКЦИЮ, С ПОМОЩЬЮ КОТОРОЙ ЗАГРУЖАЮ ДАННЫЕ В БД. ПРОБЛЕМА В СПИСКЕ МАССИВОВ, ПОТОМУ ЧТО МНЕ НУЖНО ПЕРЕДАТЬ НАБОР ДАННЫХ

 Public Function SetDBfromDataset(ByVal ds As Data.DataSet, ByVal TN As String) As Integer
DBadapter.InsertCommand = New SqlCommand
        TmpSQLstring = "INSERT INTO " amp; TN

        ' ottengo la lista dei campi
        ListFields = " ("


        For Each myCol In ds.Tables(0).Columns

            If (Not IsPrimaryCol(myCol, PKcols)) And (NormalizeDataTypeToDBtype(myCol) <> SqlDbType.Timestamp) Then
                ListFields = ListFields amp; Trim(myCol.ColumnName)
                ListFields = ListFields amp; ","
            End If
        Next
        ListFields = Mid$(ListFields, 1, Len(ListFields) - 1) amp; ")"

        'ottengo la lista dei parametri
        ListParam = " VALUES ("
        For Each myCol In ds.Tables(0).Columns
            If (Not IsPrimaryCol(myCol, PKcols)) And (NormalizeDataTypeToDBtype(myCol) <> SqlDbType.Timestamp) Then
                ListParam = ListParam amp; "@" amp; Trim(myCol.ColumnName)
                ListParam = ListParam amp; ","
                DBadapter.InsertCommand.Parameters.Add(New SqlParameter("@" amp; Trim(myCol.ColumnName), NormalizeDataTypeToDBtype(myCol)))
                DBadapter.InsertCommand.Parameters("@" amp; Trim(myCol.ColumnName)).SourceColumn = Trim(myCol.ColumnName)
            End If
        Next
        ListParam = Mid$(ListParam, 1, Len(ListParam) - 1) amp; ")"
        DBadapter.InsertCommand.CommandText = TmpSQLstring amp; ListFields amp; ListParam
        DBadapter.InsertCommand.Connection = CType(DBadapter.SelectCommand.Connection, SqlConnection)
        
 End Function
 

Комментарии:

1. Реальный вопрос в том, почему вы вводите свое значение, а не параметризуете его.

2. параметризация где?

3. VALUES (" arrText.Item(indice) ") это инъекция. Вы должны использовать параметр VALUES (@txt) и передавать значение отдельно

4. 1 К параметризации, но фактическая проблема заключается в неправильном совпадении типа данных. TestTable.riga-это не строка. Окружая значение, которое вы вставляете, знаком»», вы подразумеваете, что это так. Погода это строка или нет, типы должны совпадать

Ответ №1:

Stream s необходимо удалить, позвонив Dispose или поместив в Using блок. Это текстовый файл, так что вам даже не нужен поток.

ArrayList существует для обеспечения обратной совместимости, но вас не следует использовать в новом коде. Видишь https://docs.microsoft.com/en-us/dotnet/api/system.collections.arraylist?view=net-5.0#примечания Хорошей заменой является List(Of T)

Я разбил код на 3 метода. Вы выполняете слишком много отдельных задач одним методом. Я использовал System.IO.File класс для чтения файла. ReadAllLines возвращает массив строк в файле. Затем просто для каждого цикла определите строки, которые вы хотите добавить в базу данных. Я использовал а List(Of String) , чтобы собрать строки. Затем передайте список в код базы InsertText данных .

В цикле изменяется только значение параметра.

 Private Sub OPCode()
    Dim FilePath = GetFilePath()
    If FilePath Is Nothing Then
        MessageBox.Show("No file selected.")
    End If
    Dim lst As New List(Of String)
    Dim lines = File.ReadAllLines(FilePath)
    For Each line In lines
        If line.Contains("H06") AndAlso line.Contains("SPEKM")) Then
            lst.Add(line)
        End If
    Next
    InsertText(lst)
End Sub

Private Function GetFilePath() As String
    Dim openFileDialog1 As New OpenFileDialog()
    openFileDialog1.InitialDirectory = "Z:FitalogItaliaKMasterSPEKM"   'ATTENZIONE CAMBIARE IN "C:"
    openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
    openFileDialog1.FilterIndex = 2
    openFileDialog1.RestoreDirectory = True
    If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
        Return openFileDialog1.FileName
    Else
        Return Nothing
    End If
End Function

Private Sub InsertText(lst As List(Of String))
    Using cn As New SqlConnection("Your connection string"),
            cmd As New SqlCommand("INSERT INTO TestTable (riga) VALUES (@riga);", cn)
        cmd.Parameters.Add("@riga", SqlDbType.NVarChar)
        cn.Open()
        For Each line In lst
            cmd.Parameters("@riga").Value = line
            cmd.ExecuteNonQuery()
        Next
    End Using 'closes the connection and disposes the command and the connection
End Sub