在 SQL 查询中添加一对值作为参数

Posted

技术标签:

【中文标题】在 SQL 查询中添加一对值作为参数【英文标题】:Add pair of values as parameters in a SQL query 【发布时间】:2019-07-16 12:01:59 【问题描述】:

如何?

Dim insertQuery As String = Teilnehmerkreiszuordnung.CreateInsertSqlStatement(id, addBefugnisseIdList)
Using cn As DbConnection = DbConnection
   Using command As DbCommand = cn.CreateCommand()
      command.CommandText = insertQuery
      // Add values with parameters???
      command.ExecuteNonQuery()
   End Using
End Using

CreateInsertSqlStatement 函数:

Public Shared Function CreateInsertSqlStatement(ByVal seminarId As Integer, ByVal addBefugnisseList As List(Of Befugnisse)) As String
   Dim strIns = String.Empty
   Dim insertQuery As String = String.Empty
   If (addBefugnisseList.Any()) Then
      For i = 0 To (addBefugnisseList.Count - 1)
         strIns = strIns + String.Format("(0,1)", seminarId, addBefugnisseList(i).AutoID)
         If (addBefugnisseList.Count - 1 - i > 0) Then
            strIns = strIns + ","
         End If
      Next
      insertQuery = String.Format("INSERT INTO teilnehmerkreiszuordnung(SeminarID, befugnisID) VALUES 0", strIns)
   End If
   Return insertQuery
End Function

函数的输出如下:

INSERT INTO teilnehmerkreiszuordnung(SeminarID, befugnisID) VALUES (2,5),(2,6),(2,7)

【问题讨论】:

您能解释一下您期望的查询文本是什么吗?或者您只是想问如何用参数化查询替换您当前的字符串连接方法? 如果我理解,你必须使用参数并做 3 次插入。 如果addBefugnisseIdList 包含要使用的值,那么对CreateInsertSqlStatement 的调用已经返回一个预填充的查询字符串。只需执行它。但我建议你去准备一份声明来满足标准。 我希望查询文本是“INSERT INTO teilnehmerkreiszuordnung(SeminarID, befugnisID) VALUES (@s2, @b5),(@s2, @b6),(@s2,@b7)" 我会把逻辑改成这个。我会将 CreateInsertSqlStatement 更改为 CreateInsertSqlCommand 并让它在遍历列表时创建 DbCommand 和参数。如果需要,调用者只需调用 ExecuteNonQuery 或修复命令中的某些内容 【参考方案1】:

将代码更改为参数化查询非常简单。但是我会更改逻辑以在您遍历列表时集中创建参数。一旦你从方法中返回,这将避免第二个循环来构建参数

' pass also the connection and lets return a DbCommand filled with proper parameters'  
Public Shared Function CreateInsertSqlCommand(ByVal DbConnection cn, 
                       ByVal seminarId As Integer, 
                       ByVal addBefugnisseList As List(Of Befugnisse)) As DbCommand

   ' Use a StringBuilder to get better memory footprint with repeated string changes'

   Dim strIns As StringBuilder = new StringBuilder()

   Dim command As DbCommand = Nothing
   Dim insertQuery As String = "INSERT INTO teilnehmerkreiszuordnung(SeminarID, 
befugnisID) VALUES " 
   If (addBefugnisseList.Any()) Then
         'Create the command and add the invarian parameter'
         command As DbCommand = cn.CreateCommand()
         command.Parameters.Add("@s", mysqlDbType.Int32).Value = seminarID
         ' loop and add the list parameters while building the parameters placeholders'
         For i = 0 To (addBefugnisseList.Count - 1)
             strIns.AppendFormat($"(@s,@ai),")
             command.Parameters.Add($"ai", MySqlDbType.Int32).Value = addBefugnisseList(i).AutoID
         Next
         ' Remove the last comma'
         if strIns.Length > 0 Then
            strIns.Length = strIns.Length - 1
         End If
         command.CommandText = insertQuery + strIns.ToString()
   End If
   Return command
End Function


Using cn As DbConnection = DbConnection
   Using command As DbCommand = Teilnehmerkreiszuordnung.CreateInsertSqlCommand(cn, id, addBefugnisseIdList)
      if command IsNot Nothing Then
          command.ExecuteNonQuery()
      End If
   End Using
End Using

【讨论】:

【参考方案2】:
   Public Shared Function CreateInsertSqlCommand(ByRef command As DbCommand, ByVal seminarId As Integer, ByVal addBefugnisseList As List(Of Befugnisse)) As Boolean
        Dim IsThereAnyQuery As Boolean = False
        Dim strIns = String.Empty
        Dim insertQuery As String = String.Empty
        If (addBefugnisseList.Any()) Then
            For i = 0 To (addBefugnisseList.Count - 1)
                command.AddParameterWithValue(String.Format("@S0", i), seminarId)
                command.AddParameterWithValue(String.Format("@B0", i), addBefugnisseList(i).AutoID)
                strIns = strIns + String.Format("(@S0,@B1)", i, i)
                If (addBefugnisseList.Count - 1 - i > 0) Then
                    strIns = strIns + ","
                End If
            Next
            insertQuery = String.Format("INSERT INTO teilnehmerkreiszuordnung(SeminarID, befugnisID) VALUES 0", strIns)
            command.CommandText = insertQuery
            IsThereAnyQuery = True
        End If
        Return IsThereAnyQuery
    End Function

像这样使用这个方法:

If (Teilnehmerkreiszuordnung.CreateInsertSqlCommand(command, id, addBefugnisseIdList)) Then
     command.ExecuteNonQuery()
End If

AddParameterWithValue 方法:

public sealed class DbCommandExtensions

    public static void AddParameterWithValue(this DbCommand cmd, string name, object value)
    
       DbParameter parameter = cmd.CreateParameter();
       parameter.ParameterName = name;
       parameter.Value = RuntimeHelpers.GetObjectValue(value);
       cmd.Parameters.Add((object) parameter);
    
 

【讨论】:

以上是关于在 SQL 查询中添加一对值作为参数的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis中查询语句map的使用

SQL查询中的条件语句检查作为参数传递的多个值(列表)

SQL 在OPENQUERY中使用参数,并作为表查询对象/不允许使用远程表值函数调用。

sql 问题子查询返回的值不止一个。

SQL查询中根据表值添加条件

在输入值提示中显示 SQL 参数