【发布时间】:2020-01-29 15:56:46
【问题描述】:
我正在尝试将 SQL Server 中的数据读取到数组中。之后,我想将每一行写入单独的 .csv 文件。
这是我目前的代码:
Imports System.Data.SqlClient
Public Class Form1
Public SQLcn As New SqlConnection
Public Function Connect() As Boolean
SQLcn = New SqlConnection("Server = Server01;Database=PROD;User ID=user; Password = 123")
Try
SQLcn.Open()
Return True
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim SQLQuery As String
Dim SQLcmd As SqlCommand
Dim SQLrdr As SqlDataReader
Dim NAVArray As New ArrayList()
Call Connect()
SQLQuery = "SELECT No_ FROM " & "dbo.Database" & " Where No_ LIKE '10007*'"
SQLcmd = New SqlCommand(SQLQuery, SQLcn)
SQLrdr = SQLcmd.ExecuteReader()
While SQLrdr.Read()
Dim dict As New Dictionary(Of String, Object)
For count As Integer = 0 To (SQLrdr.FieldCount - 1)
dict.Add(SQLrdr.GetName(count), SQLrdr(count))
Next
NAVArray.Add(dict)
End While
ExportCSV(NAVArray, "\\path\path\path")
SQLcn.Close()
End Sub
Function ExportCSV(ByVal Daten As ArrayList, ByVal Pfad As String) As Boolean
Dim Nummer As Integer
For Each Nummer In Daten
Dim csv As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Pfad & Nummer, False)
csv.WriteLine("formatcount;formatname;printername;Beschreibung;")
csv.WriteLine("1;\\path\path\path\Format1.fmt;")
csv.Close()
Next
Return 0
End Function
End Class
NAVArray 甚至没有被数据填充。
另外,我不知道如何将数据写入CSV.Writeline。
编辑:
新代码(目前有效)如下所示:
Option Infer On
Option Strict On
Imports System.Data.SqlClient
Imports System.IO
Public Class Form1
Public SQLcn As New SqlConnection
Public Function GetData(databaseColumnNames As String()) As DataTable
Dim dt As New DataTable()
Dim csb As New SqlConnectionStringBuilder With {.DataSource = "NAVDB01",
.InitialCatalog = "NAV110_PROD",
.UserID = "paz",
.Password = "****"
}
Dim columnNames = " " & String.Join(", ", databaseColumnNames.Select(Function(c) "[" & c & "]")) & " "
Dim sql = "SELECT " & columnNames & " FROM [dbo.Part1 Part2$Item] WHERE No_ LIKE '10007%'"
Using conn = New SqlConnection(csb.ConnectionString),
cmd = New SqlCommand(sql, conn)
Dim DAdap As New SqlDataAdapter(cmd)
DAdap.Fill(dt)
End Using
Return dt
End Function
Function CsvLine(a As Object(), separator As Char) As String
Dim b = a.Select(Function(x) x.ToString()).ToArray()
For i = 0 To b.Count - 1
If b(i).IndexOfAny({separator, Chr(42), Chr(10), Chr(13)}) >= 0 Then
b(i) = b(i).Replace("""", """""")
b(i) = """" & b(i) & """"
End If
Next
Return String.Join(separator, b)
End Function
Sub WriteCsvFiles(destPath As String, headings As String(), dt As DataTable)
Dim separator As Char = ";"c
Dim header = String.Join(separator, headings)
For Each r As DataRow In dt.Rows
Dim destFile = Path.Combine(destPath, r(0).ToString().Trim() & ".csv")
Using sw As New StreamWriter(destFile)
sw.WriteLine(header)
sw.WriteLine(CsvLine(r.ItemArray, separator))
End Using
Next
End Sub
Private Sub bnDatenVerarbeiten_Click() Handles bnDatenVerarbeiten.Click
Dim destinationFolder = "\\fileserver02\Folder1"
Dim columnsToUseSQL = {"Description"}
Dim columnsToUseCSV = {"formatcount", "formatname", "printername", "Beschreibung"}
Dim daten = GetData(columnsToUseSQL)
WriteCsvFiles(destinationFolder, columnsToUseCSV, daten)
End Sub
End Class
关于附加输入。 将实施 5 个字段: Formatcount 作为 InputBox 格式名称为下拉 printername As Dropown(由 Formatname 定义的默认值) itemnumber 作为输入框(用作 SQL 的过滤器) 债权人作为输入框(用于第二条 SQL 语句)
直接进入 csv 的字段。 : 格式计数 格式名 打印机名称
结果到 csv 的字段。 : itemnumber(结果,例如“描述”) 债权人 (result = "specialcode";"countrycode")
EDIT2:
当前状态:
Option Infer On
Option Strict On
Imports System.Data.SqlClient
Imports System.IO
Public Class Form1
Public SQLcn As New SqlConnection
Public Function GetData(databaseColumnNames As String()) As DataTable
Dim dt As New DataTable()
Dim csb As New SqlConnectionStringBuilder With {.DataSource = "Server01",
.InitialCatalog = "NAV110_PROD",
.UserID = "paz",
.Password = "***"
}
Dim columnNames = " " & String.Join(", ", databaseColumnNames.Select(Function(c) "[" & c & "]")) & " "
Dim sql = "SELECT " & columnNames & " FROM [dbo.Part1 Part2$Item] WHERE No_ LIKE '10007%'"
Using conn = New SqlConnection(csb.ConnectionString),
cmd = New SqlCommand(sql, conn)
Dim DAdap As New SqlDataAdapter(cmd)
DAdap.Fill(dt)
End Using
Return dt
End Function
Function CsvLine(a As Object(), separator As Char) As String
Dim b = a.Select(Function(x) x.ToString()).ToArray()
For i = 0 To b.Count - 1
If b(i).IndexOfAny({separator, Chr(42), Chr(10), Chr(13)}) >= 0 Then
b(i) = b(i).Replace("""", """""")
b(i) = """" & b(i) & """"
End If
Next
Return String.Join(separator, b)
End Function
Sub WriteCsvFiles(destPath As String, headings As String(), dt As DataTable)
Dim separator As Char = ";"c
Dim header = String.Join(separator, headings)
For Each r As DataRow In dt.Rows
Dim destFile = Path.Combine(destPath, r(0).ToString().Trim() & ".csv")
Using sw As New StreamWriter(destFile)
sw.WriteLine(header)
sw.WriteLine(CsvLine(r.ItemArray, separator))
End Using
Next
End Sub
Private Sub bnDatenVerarbeiten_Click() Handles bnDatenVerarbeiten.Click
Dim destinationFolder = "\\fileserver02\folder"
Dim Anzahl = 1
Dim Format = "\\fileserver02\folder2"
Dim Drucker = "\\PRNSRV\Druckdruck"
Dim columnsToUseSQL = {"Description", "Description 2"}
Dim columnsToUseCSV = {"Beschreibung", "Beschreibung 2", "formatcount", "formatname", "printername"}
Dim daten = GetData(columnsToUseSQL)
daten.Columns.Add("formatcount", GetType(Integer))
daten.Columns.Add("formatname", GetType(String))
daten.Columns.Add("printername", GetType(String))
daten.Rows.Add(daten.Rows(0).Item("Description"), daten.Rows(0).Item("Description 2"), Anzahl, Format, Drucker)
WriteCsvFiles(destinationFolder, columnsToUseCSV, daten)
End Sub
End Class
【问题讨论】:
-
您确定查询返回任何内容吗?你真的有一个名为
Database的表吗?你测试过查询吗?连接字符串来创建 SQL 查询是一个非常糟糕的主意,但这次它什么也没做,你可以只写"SELECT No_ FROM dbo.Database Where No_ LIKE '10007*'"。 -
SQL Server 中的通配符是
%,表示多个字符,_表示单个字符:LIKE (Transact-SQL) documentation。 -
For Each Nummer In Daten字典的 ArrayList 怎么会有整数? -
这个
GetData()方法将迫使您以一种极易受到SQL 注入问题攻击的方式构建SQL 查询。
标签: .net sql-server vb.net