VB.Net 和 SQL 命令未处理的异常
VB.Net and SQL Command Unhandled Exception
我正在构建一个用于批量加载到 SQL 的简单程序。但是我无法弄清楚这个错误。下面是原始代码,然后是没有文本框引用的翻译代码。
进口System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
" FROM " + path.Text +
" With (FIRSTROW = '" + firstrow.Text + "',
FIELDTERMINATOR = '" + seperator.Text + "',
ROWTERMINATOR= '\n');", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
这是 SQL 部分将翻译成的内容
SQLCMD = New SqlCommand("BULK INSERT test1
FROM 'C:\Program Files\Servers\FFA\csgo\maplist.txt'
With (FIRSTROW = '2',
FIELDTERMINATOR = ' ',
ROWTERMINATOR= '\n')";, SQLCONN)
这是我得到的错误:
System.Data.SqlClient.SqlException: ''C:' 附近的语法不正确。
关键字 'with' 附近的语法不正确。如果此语句是一个常见的 table 表达式、一个 xmlnamespaces 子句或一个更改跟踪上下文子句,则前面的语句必须以分号结尾。'
谁能帮我弄清楚为什么会出错?
您需要从 FIRSTROW
值
中删除双引号
SQLCMD = New SqlCommand("BULK INSERT test1
FROM 'C:\Program Files\Servers\FFA\csgo\maplist.txt'
With (FIRSTROW = 2,
FIELDTERMINATOR = ' ',
ROWTERMINATOR= '\n')";, SQLCONN)
您的 class 将如下所示
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
" FROM " + path.Text +
" With (FIRSTROW = " + firstrow.Text + ",
FIELDTERMINATOR = '" + seperator.Text + "',
ROWTERMINATOR= '\n');", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
您的 SQL 在文件名周围有引号,但 VB 版本没有(除非文本框本身包含引号,但鉴于错误消息,我认为这不太可能):
如果您使用字符串插值并在构建字符串之外进行一些预处理,您的 SQL 将更具可读性:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
Dim p = path.Text.Replace("'","''")
Dim f = seperator.Text.Replace("'","''")
SQLCMD = New SqlCommand($"BULK INSERT QUOTENAME({table.Text})
FROM '{p}'
WITH (FIRSTROW = {firstrowNumericUpdown.Value}
FIELDTERMINATOR = '{f}',
ROWTERMINATOR= '\n')", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
您还应该尽最大努力防止 SQL 注入;您正在向用户提供几个文本框,他们可以在其中键入内容,如果他们决定在文本框
中写一些 SQL ,这可能会非常危险
- 考虑使用 QUOTENAME table 名字
- 为您的 FIRSTROW 使用 NumericUpDown
- 考虑在其他字段中将“替换为”
- 考虑将
seperator
文本框的长度限制为 MaxLength=1
如果您不知道什么是 SQL 注入黑客,请阅读 http://bobby-tables.com
谢谢大家,你们的所有回复对我帮助很大。我决定在项目上走另一条路,再次感谢!
我正在构建一个用于批量加载到 SQL 的简单程序。但是我无法弄清楚这个错误。下面是原始代码,然后是没有文本框引用的翻译代码。
进口System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
" FROM " + path.Text +
" With (FIRSTROW = '" + firstrow.Text + "',
FIELDTERMINATOR = '" + seperator.Text + "',
ROWTERMINATOR= '\n');", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
这是 SQL 部分将翻译成的内容
SQLCMD = New SqlCommand("BULK INSERT test1
FROM 'C:\Program Files\Servers\FFA\csgo\maplist.txt'
With (FIRSTROW = '2',
FIELDTERMINATOR = ' ',
ROWTERMINATOR= '\n')";, SQLCONN)
这是我得到的错误:
System.Data.SqlClient.SqlException: ''C:' 附近的语法不正确。 关键字 'with' 附近的语法不正确。如果此语句是一个常见的 table 表达式、一个 xmlnamespaces 子句或一个更改跟踪上下文子句,则前面的语句必须以分号结尾。'
谁能帮我弄清楚为什么会出错?
您需要从 FIRSTROW
值
SQLCMD = New SqlCommand("BULK INSERT test1
FROM 'C:\Program Files\Servers\FFA\csgo\maplist.txt'
With (FIRSTROW = 2,
FIELDTERMINATOR = ' ',
ROWTERMINATOR= '\n')";, SQLCONN)
您的 class 将如下所示
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
" FROM " + path.Text +
" With (FIRSTROW = " + firstrow.Text + ",
FIELDTERMINATOR = '" + seperator.Text + "',
ROWTERMINATOR= '\n');", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
您的 SQL 在文件名周围有引号,但 VB 版本没有(除非文本框本身包含引号,但鉴于错误消息,我认为这不太可能):
如果您使用字符串插值并在构建字符串之外进行一些预处理,您的 SQL 将更具可读性:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
Dim SQLCONN As New SqlConnection
Dim SQLCMD As New SqlCommand
SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
SQLCONN.Open()
Dim p = path.Text.Replace("'","''")
Dim f = seperator.Text.Replace("'","''")
SQLCMD = New SqlCommand($"BULK INSERT QUOTENAME({table.Text})
FROM '{p}'
WITH (FIRSTROW = {firstrowNumericUpdown.Value}
FIELDTERMINATOR = '{f}',
ROWTERMINATOR= '\n')", SQLCONN)
SQLCMD.ExecuteNonQuery()
SQLCONN.Close()
End Sub
您还应该尽最大努力防止 SQL 注入;您正在向用户提供几个文本框,他们可以在其中键入内容,如果他们决定在文本框
中写一些 SQL ,这可能会非常危险- 考虑使用 QUOTENAME table 名字
- 为您的 FIRSTROW 使用 NumericUpDown
- 考虑在其他字段中将“替换为”
- 考虑将
seperator
文本框的长度限制为MaxLength=1
如果您不知道什么是 SQL 注入黑客,请阅读 http://bobby-tables.com
谢谢大家,你们的所有回复对我帮助很大。我决定在项目上走另一条路,再次感谢!