#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