2016-07-21 2 views
0

私のAutoCADプラグインアプリケーションでこのSQLエラーが発生しました。 "[トークン行番号= 1、トークン行オフセット= 110、トークンエラー中= desc]"。私はdbText情報をプルするテーブルをステップし、それをデータベースに渡します。いくつかの投稿に基づいて、私は値の前にテーブル名と@の前後に[]を追加しようとしましたが、どちらの解決策も機能しませんでした。vb.net - SQL - クエリのパージエラー。

 Using myTrans As Transaction = myDB.TransactionManager.StartTransaction 
     Dim myLayerTable As LayerTable = myDB.LayerTableId.GetObject(OpenMode.ForRead) 
     For Each myLayerID As ObjectId In myLayerTable 
      Dim myLayer As LayerTableRecord = myLayerID.GetObject(OpenMode.ForRead) 
      If myLayer <> Nothing Then 
       Dim name As String = myLayer.Name, 
        isoff As Boolean = myLayer.IsOff, 
        frozen As Boolean = myLayer.IsFrozen, 
        locked As Boolean = myLayer.IsLocked, 
        color As String = myLayer.Color.ColorNameForDisplay, 
        linetype As String = myLayer.LinetypeObjectId.ToString, 
        lineweight As String = myLayer.LineWeight.ToString, 
        transparency As String = myLayer.Transparency.ToString, 
        plotstyle As String = myLayer.PlotStyleNameId.ToString, 
        isplottable As Boolean = myLayer.IsPlottable, 
        vv As Boolean = myLayer.ViewportVisibilityDefault, 
        desc As String = myLayer.Description 
       Dim nd As String = "INSERT INTO layers (name, isoff, frozen, locked, color, linetype, lineweight, transparency, isplottable, vv, desc) " & _ 
                  "VALUES (" & _ 
                  "'" & name & "', " & _ 
                  "'" & isoff & "', " & _ 
                  "'" & frozen & "', " & _ 
                  "'" & locked & "', " & _ 
                  "'" & color & "', " & _ 
                  "'" & linetype & "', " & _ 
                  "'" & lineweight & "', " & _ 
                  "'" & transparency & "', " & _ 
                  "'" & isplottable & "', " & _ 
                  "'" & vv & "', " & _ 
                  "'" & desc & "')" 
       CeCon.DataUpdate(nd) 
      End If 
     Next 
     myTrans.Abort() 
    End Using 
Private CeCon As New SqlCeConnection("Data Source=D:\Documents\Test.sdf;Persist Security Info=False;") 
Private CeCmd As SqlCeCommand 
Public CeDA As SqlCeDataAdapter 
Public CeDT As DataTable 
Public Params As New List(Of SqlCeParameter) 
Public RecordCount As Integer 
Public Exception As String 
Public Sub ExecQuery(Query As String) 
    ' Reset query stats 
    RecordCount = 0 
    Exception = "" 
    Try 
     CeCon.Open() 
     CeCmd = New SqlCeCommand(Query, CeCon) 
     Params.ForEach(Sub(p) CeCmd.Parameters.Add(p)) 
     Params.Clear() 
     CeDT = New DataTable 
     CeDA = New SqlCeDataAdapter(CeCmd) 
     RecordCount = CeDA.Fill(CeDT) 
    Catch ex As Exception 
     Exception = ex.Message 
    Finally 
     If CeCon.State = ConnectionState.Open Then CeCon.Close() 
    End Try 
End Sub 
Public Function DataUpdate(Command As String) As Integer 
    Try 
     CeCon.Open() 
     CeCmd = New SqlCeCommand(Command, CeCon) 
     Dim ChangeCount As Integer = CeCmd.ExecuteNonQuery 
     CeCon.Close() 
     Return ChangeCount 
    Catch ex As Exception 
     MsgBox(ex.Message) 
    End Try 
    If CeCon.State = ConnectionState.Open Then CeCon.Close() 
    Return 0 
End Function 
+1

変数の中に一重引用符が含まれているとしたら、どうなると思いますか? – Steve

+0

エラーメッセージとは何ですか?「クエリをパースする」とは何を意味していますか?また、ダンプはすべての目的のSQLデリミタではありません。あなたは数字であるように見え、その混乱の中で文字列を強制されるブール値を持っています。 – Plutonix

+1

ところで、DESCはこの世界のどのSQLデータベースでも予約されているキーワードです。その言葉の周りに大括弧が必要です。 [desc]またはその名前を問題のないものに変更する – Steve

答えて

1

DESCは、この世界のどのSQLデータベースでも予約済みのキーワードです。その言葉の周りに大括弧が必要です。その名前を問題の少ないものに変更してください。

これはあなたのコードで唯一の問題ではありません。これらの変数のいずれかに単一引用符が含まれていると、文字列の連結によって無効なsqlコマンドが生成されます。ですから、

Dim nd As String = "INSERT INTO layers 
    (name, isoff, frozen, locked, color, linetype, lineweight, 
    transparency, isplottable, vv, [desc]) 
    VALUES (@name, @isoff, @frozen, @locked, @color, @linetype, @lineweight, 
      @transparency, @isplottable, @vv, @desc)" 
Dim prms = new List(Of SqlCeParameter)() 
prms.Add(new SqlCeParameter("@name", SqlDbType.NVarChar) With {.Value = name}) 
prms.Add(new SqlCeParameter("@isoff", SqlDbType.Bit) With {.Value = isoff}) 
prms.Add(new SqlCeParameter("@frozen", SqlDbType.Bit) With {.Value = frozen}) 
prms.Add(new SqlCeParameter("@locked", SqlDbType.Bit) With {.Value = locked}) 
prms.Add(new SqlCeParameter("@color", SqlDbType.NVarChar) With {.Value = color}) 
prms.Add(new SqlCeParameter("@linetype", SqlDbType.NVarChar) With {.Value = linetype}) 
prms.Add(new SqlCeParameter("@lineweight", SqlDbType.NVarChar) With {.Value = lineweight}) 
prms.Add(new SqlCeParameter("@transparency", SqlDbType.NVarChar) With {.Value = transparency}) 
prms.Add(new SqlCeParameter("@isplottable", SqlDbType.Bit) With {.Value = isplottable}) 
prms.Add(new SqlCeParameter("@vv", SqlDbType.Bit) With {.Value = vv}) 
prms.Add(new SqlCeParameter("@desc", SqlDbType.NVarChar) With {.Value = desc}) 
CeCon.DataUpdate(nd, prms) 

パラメータ化クエリを必要とする。これは、あなたが受信するデータ更新手順を変更することも必要があることを意味

(私はあなたが自分で簡単にデータベースを破壊する可能性がSql Injectionに接続されている問題を発見してみましょう)パラメータ値のリスト

Public Function DataUpdate(Command As String, prms As List(Of SqlCeParameter)) As Integer 
    Try 
     CeCon.Open() 
     CeCmd = New SqlCeCommand(Command, CeCon) 
     if prms Is Not Nothing Then 
      CeCmd.Parameters.AddRange(prms.ToArray()) 
     End if 
     Dim ChangeCount As Integer = CeCmd.ExecuteNonQuery 
     CeCon.Close() 
     Return ChangeCount 
    Catch ex As Exception 
     MsgBox(ex.Message) 
    End Try 
    If CeCon.State = ConnectionState.Open Then CeCon.Close() 
    Return 0 
End Function