2016-09-05 4 views
2

IN 절을 사용하여 업데이트하려고하지만 작동하지 않을 수 있습니다. 내 iArr은 쉼표로 구분 된 숫자 목록을 만들고 이론상 괄호로 묶인 후에는 업데이트해야하지만 제대로 작동하지는 않습니다. 계속 오류가 발생합니다.IN 절에 대한 매개 변수를 사용하는 SQL Server 쿼리

nvarchar 값 '111111, 222222, 333333'을 데이터 유형 int로 변환 할 때 변환하지 못했습니다.

아무리 생각해도 될까요? 아래의 전체 코드 :

Dim iArr As String 
    iArr = "" 
    For i As Integer = 0 To ufReview.InvoiceGrid.Rows.Count - 1 
     iArr = iArr & ufReview.InvoiceGrid.Rows(i).Cells(0).Value & ", " 
    Next i 
    iArr = Left(iArr, Len(iArr) - 2) 

    Dim SQL_Arr As String = _ 
      <SQL> 
       UPDATE SCInv SET Inv_Transfer_Date = @UpdateCommand WHERE Inv_Num IN (@Array) 
      </SQL> 

    Dim cnt As New SqlConnection() 
    Dim cmd As New SqlCommand() 
    cnt.ConnectionString = "Data Source=SERVERNAME;Initial Catalog=CAT;User ID=USERID;Password=PASSWORD" 
    Try 
     cnt.Open() 
     cmd.Connection = cnt 
     cmd.CommandText = SQL_Arr 
     cmd.Parameters.Clear() 
     cmd.Parameters.AddWithValue("@UpdateCommand", UpdateCommand) 
     cmd.Parameters.AddWithValue("@Array", iArr) 
     Dim RACount As Integer = cmd.ExecuteNonQuery() 
     MsgBox("The following Summary Numbers are now marked as " & UpdateFeedback & ": " & vbCrLf & iArr _ 
       & vbCrLf & vbCrLf & "(" & RACount & " row(s) affected)", vbOKOnly + vbInformation, "Tesseract") 
    Catch ex As Exception 
     MsgBox("Failed to update, please try again" & vbCrLf & vbCrLf & ex.Message, vbOKOnly + vbCritical, "SQL Error") 
    End Try 
    cnt.Close() 
    cnt.Dispose() 
+0

이것은 답변이 아니지만 아마도 WHERE 절을 매개 변수화해야합니다. 나는 SQL 인젝터가 현재 가지고있는 것과 함께 입안에 거품을 일으킬 것이라고 생각한다. –

+0

먼저 공급자가 매개 변수에 대한 배열을 허용하는지 확인합니다. 나는 항상 형식화하고 확장해야했습니다. – Plutonix

+0

배열을'('item1, item2')'에서'('item1', 'item2')' –

답변

1

SQL 서버는 이제 매개 변수 배열을 전달하는 지원 가능하다. 많은 DB는 그렇지 않으며 아직까지 Microsoft Connect에 대한 공개 요청이 있습니다. 알아내는 것이 가치가있을 것입니다.

Option Strict도 켜야합니다. SQL_Arr은 string으로 선언되었지만 XML 리터럴을 지정한 다음 해당 리터럴을 명령 텍스트로 전달합니다.

ID 목록의 각 항목에 고유 한 매개 변수가 지정된 SQL 문과이 매개 변수에 대해 설정된 값이 SQL 문으로 작성됩니다. Id에 대한 임의의 데이터를 사용하여 다양한 목록을 에뮬레이트하고 MySQL을 사용합니다 ... 개념은 동일합니다. ID를 업데이트 할 수 있기 때문에 그들 중 많은 - 첫 번째 부분은 @q1 자리의 목록을 만듭니다 있도록

' test data: random set of IDs to update 
Dim idList = Enumerable.Range(1, 2500).OrderBy(Function(r) RNG.Next()).Take(8).ToList() 

Dim sql As String = <sql> 
      UPDATE SampleX SET `Value`= @v WHERE Id IN (@theList) 
      </sql>.Value 

' create the parameter placeholders 
' results in a list of "@pX" items where X is a number 
Dim params = Enumerable.Range(1, idList.Count). 
      Select(Function(q) String.Format("@q{0}", q)). 
      ToList() 

' join the list of parms to make '@q1, @q2...' 
' then replace @thelist with that string 
sql = sql.Replace("@theList", String.Join(",", params)) 

' run the query 
Using dbcon As New MySqlConnection(MySQLConnStr) 
    Using cmd As New MySqlCommand(sql, dbcon) 

     ' specify the value 
     cmd.Parameters.Add("@v", MySqlDbType.Int32).Value = -6 

     ' loop to supply an Id value for each IN parameter 
     ' placeholder created 
     For n As Int32 = 0 To params.Count - 1 
      cmd.Parameters.Add(params(n), MySqlDbType.Int32).Value = idList(n) 
     Next 

     dbcon.Open() 
     Dim rows = cmd.ExecuteNonQuery() 
    End Using 

    ' debug/demo: show the results 
    sql = "SELECT Name, Descr, Value, Country FROM SampleX WHERE Value=-6" 
    Using cmd As New MySqlCommand(sql, dbcon) 
     dtSample = New DataTable 
     dtSample.Load(cmd.ExecuteReader()) 
     dgv1.DataSource = dtSample 
    End Using 
End Using 

우리는 쿼리 매개 변수가 유지합니다. 루프에서 자리를 만들려면 :

Dim params As New List(Of String) 
For n As Int32 = 0 To idList.Count - 1 
    params.Add(String.Format("@q{0}", (n + 1).ToString())) 
Next 

다음 코드는 목록의 결합 된 버전의 SQL에 @theList을 대체합니다. 그 결과

UPDATE SampleX SET `Value`= @v WHERE Id IN (@q1,@q2,@q3,@q4,@q5,@q6,@q7,@q8) 

IN 절은 매개 변수 생성에 틱을 추가, 정수가 아닌 문자열을 다루는 경우 : String.Format("'@q{0}'",...

을 나머지는 정직 : 지정 이드 각 매개 변수 :

' params(n) e.g. "q1" and idList(n) is the value e.g. 11111 
cmd.Parameters.Add(params(n), MySqlDbType.Int32).Value = idList(n) 

내 샘플은 값을 쉽게 찾을 수 있도록 -6으로 설정했습니다. 그것은 작동 :

마지막으로

enter image description here

, 결과 SQL에 허용되는 최대 길이 있음을 유의하십시오. 최대 값은 DB 제공자에 따라 다르지만 꽤 크지 만 IN 절에 대해 많은 수의 ID가있는 경우 일괄 처리로 분할 할 수 있습니다.