Как передать параметр SQL, когда его слишком долго - PullRequest
2 голосов
/ 17 ноября 2011

У меня есть очень большой оператор 'Where', который длиннее максимально допустимого.

В настоящее время я собираю полный SQL в коде vb.net и выполняю его.

Проблема в том, что этот способ известен как медленный, потому что это не скомпилированный запрос.

Есть ли другой способ сделать это?

РЕДАКТИРОВАТЬ:

  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()

Ответы [ 3 ]

2 голосов
/ 18 ноября 2011

Вместо создания оператора SQL на клиенте вы можете вызвать хранимую процедуру и передать значения в DataTable. В вашей хранимой процедуре присоединитесь к передаваемым значениям, что означает, что вам не нужно будет создавать длинный динамический SQL-оператор, и снизит риск атаки SQL-инъекцией.

Например, если вы создадите этот тип и процедуру в своей базе данных (я предполагаю, что здесь для типов данных):

create type dbo.OrderIdInfo as table
(
    OrderId nvarchar(20)
)

create procedure dbo.SelectOrders
(
    @orderIds dbo.OrderIdInfo readonly
)
as

    select o.* 
    from OrderPickSheet o
        inner join @orderIds i on o.OrderId = i.OrderId
    where o.Status > -1
    order by o.SortOrder

Вы можете вызвать процедуру, как показано ниже. Код работает (проверено в 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
1 голос
/ 18 ноября 2011

Вы можете сохранить достаточное количество длины в команде 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()
1 голос
/ 18 ноября 2011

Вы можете создавать SQL динамически в хранимой процедуре, а не в .NET.

Запрос по-прежнему не будет скомпилирован, но вы можете передать все свои переменные через строку с разделителями-запятыми или XML

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...