Передача Списка <> к Хранимой процедуре SQL

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

50
задан Drew 8 October 2013 в 15:56
поделиться

7 ответов

Если движение к SQL Server, 2008 является опцией для Вас, существует новая возможность, названная "Табличные параметры" для решения этой точной проблемы.

Выезд больше деталей о TVP здесь и здесь или просто просит у Google "SQL Server 2008 табличные параметры" - Вы найдете много информации и образцов.

Наиболее рекомендуемый - , если можно переместить в SQL Server 2008...

34
ответ дан Tim Cooper 7 November 2019 в 11:01
поделиться

Ваша строковая логика соединения может, вероятно, быть упрощена:

string items = 
    string.Join("~", itemList.Select(item=>item.ToString()).ToArray());

, Который сохранит Вас некоторая конкатенация строк, которая является дорогой в.Net.

я не думаю, что что-либо неправильно со способом, которым Вы сохраняете объекты. Вы ограничиваете прохождения в дб, который является хорошей вещью. Если бы Ваша структура данных была более сложной, чем список ints, я предложил бы XML.

Примечание: меня спросили в комментариях, если это сохранит нас какая-либо конкатенация строк (она делает действительно). Я думаю, что это - превосходный вопрос и хотело бы следовать этому.

, Если Вы очищаете открытую строку. Соединение с Отражатель Вы будете видеть, что Microsoft использует несколько небезопасные (в.Net значении слова) методы, включая использование символьного указателя и структуры под названием UnSafeCharBuffer. То, что они делают, когда Вы действительно излагаете его кратко, использует указатели, чтобы идти через пустую строку и создать соединение. Помните, что главная причина, конкатенация строк является столь дорогой в.Net, состоит в том, что новый строковый объект помещается в "кучу" для каждой конкатенации, потому что строка неизменна. Те операции памяти являются дорогими. Строка. Соединение (..) по существу выделяет память однажды, затем работая на него с указателем. Очень быстро.

19
ответ дан Jason Jackson 7 November 2019 в 11:01
поделиться

Одна потенциальная проблема с Вашей техникой - то, что она не обрабатывает очень большие списки - можно превысить максимальную длину строки для базы данных. Я использую вспомогательный метод, который связывает целочисленные значения в перечисление строк, каждая из которых является меньше, чем указанный максимум (следующая реализация также дополнительно проверяет на и удаляет идентификаторы дубликатов):

public static IEnumerable<string> ConcatenateValues(IEnumerable<int> values, string separator, int maxLength, bool skipDuplicates)
{
    IDictionary<int, string> valueDictionary = null;
    StringBuilder sb = new StringBuilder();
    if (skipDuplicates)
    {
        valueDictionary = new Dictionary<int, string>();
    }
    foreach (int value in values)
    {
        if (skipDuplicates)
        {
            if (valueDictionary.ContainsKey(value)) continue;
            valueDictionary.Add(value, "");
        }
        string s = value.ToString(CultureInfo.InvariantCulture);
        if ((sb.Length + separator.Length + s.Length) > maxLength)
        {
            // Max length reached, yield the result and start again
            if (sb.Length > 0) yield return sb.ToString();
            sb.Length = 0;
        }
        if (sb.Length > 0) sb.Append(separator);
        sb.Append(s);
    }
    // Yield whatever's left over
    if (sb.Length > 0) yield return sb.ToString();
}

Тогда Вы используете его что-то как:

using(SqlCommand command = ...)
{
    command.Connection = ...;
    command.Transaction = ...; // if in a transaction
    SqlParameter parameter = command.Parameters.Add("@Items", ...);
    foreach(string itemList in ConcatenateValues(values, "~", 8000, false))
    {
        parameter.Value = itemList;
        command.ExecuteNonQuery();
    }
}
8
ответ дан Joe 7 November 2019 в 11:01
поделиться

Вы или делаете то, что Вы уже получили, передача в разграниченной строке и затем анализируете к табличному значению, или другой выбор является передающим в wodge XML и довольно почти таким же:

http://weblogs.asp.net/jgalloway/archive/2007/02/16/passing-lists-to-sql-server-2005-with-xml-parameters.aspx

у меня не было шанса посмотреть на SQL 2008 все же, чтобы видеть, добавили ли они новую функциональность для обработки этого типа вещи.

5
ответ дан Kev 7 November 2019 в 11:01
поделиться

См. http://www.sommarskog.se/arrays-in-sql-2005.html для детального обсуждения этой проблемы и разных подходов, которые Вы могли использовать.

2
ответ дан Phillip Wells 7 November 2019 в 11:01
поделиться

запрашивают единственное поле для нескольких значений в хранимой процедуре
http://www.norimek.com/blog/post/2008/04/Query-a-Single-Field-for-Multiple-Values-in-a-Stored-Procedure.aspx

1
ответ дан Robert Harvey 7 November 2019 в 11:01
поделиться

Почему бы не использовать параметр с табличным значением? https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters

5
ответ дан 7 November 2019 в 11:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: