Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net SQL参数太长时如何传入_.net_Sql Server 2008 - Fatal编程技术网

.net SQL参数太长时如何传入

.net SQL参数太长时如何传入,.net,sql-server-2008,.net,Sql Server 2008,我有一个非常大的“Where”语句,比允许的最大值要长 目前,我在vb.net代码中构建完整的sql并执行它 问题是,众所周知,这种方法速度很慢,因为它不是一个已编译的查询 还有别的办法吗 编辑: For i As Integer = 0 To List.Count - 1 If Filter = String.Empty Then Filter = " Where OrderID = " Else Filter

我有一个非常大的“Where”语句,比允许的最大值要长

目前,我在vb.net代码中构建完整的sql并执行它

问题是,众所周知,这种方法速度很慢,因为它不是一个已编译的查询

还有别的办法吗

编辑:

  For i As Integer = 0 To List.Count - 1
        If Filter = String.Empty Then
            Filter = " Where OrderID = "
        Else
            Filter += " OR OrderID ="
        End If
        Filter = Filter + "(" & List(i) + ")"
    Next

    Sql = "Select * from OrderPickSheet " & Filter & " And Status > -1 Order by SortOrder"
    cmd.CommandText = Sql
    cmd.ExecuteReader()

您可以在存储过程中而不是在.NET中动态创建SQL


查询仍然不会被编译,但您可以通过逗号分隔字符串或XML将所有变量传入,而不是在客户端上构造SQL语句,您可以调用存储过程并在
数据表中传递值。在存储过程中,加入传入的值,这意味着您不需要构建长的动态sql语句,并降低sql注入攻击的风险

例如,如果在数据库中创建此类型和过程(我在这里猜测数据类型):

您可以调用如下所示的过程。代码确实运行(在LINQPad中测试),但VB不是我的主要语言,请原谅我的笨拙:

Dim table As New DataTable
Dim results As New DataTable

table.Columns.Add("OrderId", GetType(String))

table.Rows.Add("1")
table.Rows.Add("2")
table.Rows.Add("4")

Dim parameter As New SqlParameter("@orderIds", SqlDbType.Structured)

parameter.Value = table

Using connection As SqlConnection = New SqlConnection("server=localhost;database=Test;integrated security=true")
    Using command As SqlCommand = connection.CreateCommand()

        command.CommandText = "dbo.SelectOrders"
        command.CommandType = CommandType.StoredProcedure
        command.Parameters.Add(parameter)

        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        results.Load(reader)

    End Using
End Using

通过动态构建一组参数,您可以在SQL命令中节省相当长的时间(并保护自己免受SQL注入攻击,以便启动):

    Dim paramList As New StringBuilder
    For i As Integer = 0 To List.Count - 1
        Dim paramName As String = String.Format("@p{0}", i)
        If paramList.Length > 0 Then
            paramList.Append(",")
        End If
        paramList.Append(String.Format(paramName))
        cmd.Parameters.AddWithValue(paramName, List(i))
    Next
    cmd.CommandText = "Select * from OrderPickSheet Where OrderID in (" & paramList.ToString() & ") And Status > -1 Order by SortOrder"
    cmd.ExecuteReader()

那么问题是它的速度慢,还是它不工作?SP不工作是因为参数。太长了。硬编码完整的查询速度很慢。@Ezi:这没有意义。如果将查询设置为存储过程,那么哪个参数太长?当你说“硬编码整个查询很慢”时,你在哪里硬编码?为什么不发布查询,包括查询周围的当前.NET代码?我想打印列表中所有选定行的报告。因此,我获取所有ID并构建一个where语句。我将添加代码示例。谁说它太长了-您得到了什么错误,在哪里?使查询稍微小一点的一种方法可能是将“orderID=x或orderID=y…”序列替换为“orderID IN(x,y,…”。我无法发送它,因为它太长了。您不必使用长WHERE语句。如果将SQL创建移动到存储过程中。将所有条件放入表变量后,可以使用IN语句。有了一个好的索引,您可以进一步提高查询的性能。我有一个列表中的所有id,我如何将其发送到sql?@Ezi-如果您不想像adrift建议的那样使用TVP,请看下面的几种方法。
    Dim paramList As New StringBuilder
    For i As Integer = 0 To List.Count - 1
        Dim paramName As String = String.Format("@p{0}", i)
        If paramList.Length > 0 Then
            paramList.Append(",")
        End If
        paramList.Append(String.Format(paramName))
        cmd.Parameters.AddWithValue(paramName, List(i))
    Next
    cmd.CommandText = "Select * from OrderPickSheet Where OrderID in (" & paramList.ToString() & ") And Status > -1 Order by SortOrder"
    cmd.ExecuteReader()