Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Передача массивов в хранимые процедуры  [new]
Warlom
Member

Откуда:
Сообщений: 33
Здравствуйте!
Пишу хранимые процедуры для добавления/удаление/изменения элементов таблиц базы.
Столкнулся со следующей проблемой:
В базе присутствуют связи один ко многим и следовательно при добавлении основного элемента и связывая его с позициями справочника мне приходится несколько раз вызывать хранимую процедуру для каждой пары связей.
Вопрос: можно ли каким-то образом передавать в хранимку массив? и если можно то как?
12 апр 11, 15:18    [10506918]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
Warlom,

передавайте xml внутри превращаете его в таблицу и вуаля.
12 апр 11, 15:23    [10506965]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Sergey Sizov
Member

Откуда:
Сообщений: 1579
Warlom
Здравствуйте!
Пишу хранимые процедуры для добавления/удаление/изменения элементов таблиц базы.
Столкнулся со следующей проблемой:
В базе присутствуют связи один ко многим и следовательно при добавлении основного элемента и связывая его с позициями справочника мне приходится несколько раз вызывать хранимую процедуру для каждой пары связей.
Вопрос: можно ли каким-то образом передавать в хранимку массив? и если можно то как?
А Вы видели в сервере массивы?

ps: процедуры надо писать не на одну запись, а на набор записей.
12 апр 11, 15:24    [10506981]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
https://www.sql.ru/articles/mssql/03060701ArraysAndListsInSQLServer.shtml
12 апр 11, 15:26    [10506993]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Warlom
Member

Откуда:
Сообщений: 33
Sergey Sizov
Warlom
Здравствуйте!
Пишу хранимые процедуры для добавления/удаление/изменения элементов таблиц базы.
Столкнулся со следующей проблемой:
В базе присутствуют связи один ко многим и следовательно при добавлении основного элемента и связывая его с позициями справочника мне приходится несколько раз вызывать хранимую процедуру для каждой пары связей.
Вопрос: можно ли каким-то образом передавать в хранимку массив? и если можно то как?
А Вы видели в сервере массивы?

ps: процедуры надо писать не на одну запись, а на набор записей.


да я бы и рад но дело в том что в одном случае процедура должна принять 3 параметра, в другом 4, а потом и все 7, например
12 апр 11, 15:33    [10507045]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Если 2008 R2 - то BOL->Table-Valued Parameters
12 апр 11, 15:59    [10507262]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Передача массивов в хранимые процедуры  [new]
FatherSql
Member

Откуда:
Сообщений: 3812
а почему такой отстой что нет массивов? это ж для студентов поделка получается, столько гемора словить из обыденной задачи передать массив параметров
31 мар 14, 13:11    [15810810]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
FatherSql
а почему такой отстой что нет массивов?

Потому что таблица - это уже двумерный массив
31 мар 14, 13:13    [15810822]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
Массив не является реляционным набором данных.
31 мар 14, 13:38    [15811019]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
FatherSql
Member

Откуда:
Сообщений: 3812
Владислав Колосов
Массив не является реляционным набором данных.

оракл это не смутило
31 мар 14, 13:51    [15811108]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
FatherSql
оракл это не смутило

вам туда
31 мар 14, 13:52    [15811121]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
dvim
Member

Откуда: Санкт Петербург
Сообщений: 711
а почему такой отстой что нет массивов?

ну вообще... массивы есть.


читать
В общем для ряда задач очень быстрое решение
31 мар 14, 14:00    [15811182]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Jaffar
Member

Откуда:
Сообщений: 633
dvim,

если нужно передать массив - можно поступить старым олдфаговским методом - собрать все параметры в 1 строку и передать - а внутри распарсить.
31 мар 14, 14:52    [15811490]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
FatherSql
Member

Откуда:
Сообщений: 3812
а как курсоры применяются? прочитал тут но не понял как передать. Ведь курсор это просто селект по которому пробежать можно типа for each если кто в теме.
31 мар 14, 14:53    [15811503]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
FatherSql
Member

Откуда:
Сообщений: 3812
не понял как табличный тип заполнить на клиенте (шарпе)? пример приведите. поиском пока не нашел.
31 мар 14, 15:02    [15811569]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
_djХомяГ
Guest
Нуууууу есть еще косячный метод это заполнять "постоянную" таблицу и обращаться к ней по SPID Только потом при параллельно й работе пользователей могут наблюдаться блокировки при insert/delete
Вообщем данный способ использовать не желательно
31 мар 14, 15:11    [15811636]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
FatherSql
не понял как табличный тип заполнить на клиенте (шарпе)? пример приведите. поиском пока не нашел.
Я обычно пользуюсь INSERTом SELECT ... UNION ALL SELECT ... непосредственно перед вызовом функции.
Этот INSERT формирует у меня клиент, а данные берёт из грида.
31 мар 14, 15:38    [15811842]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6202
FatherSql
не понял как табличный тип заполнить на клиенте (шарпе)? пример приведите. поиском пока не нашел.

https://www.google.ru/search?q=c# sql server table valued parameter
31 мар 14, 15:39    [15811855]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
FatherSql
Member

Откуда:
Сообщений: 3812
приведу сюда шоб не искать
DataTable dataTable = new DataTable("SampleDataType"); 
//we create column names as per the type in DB 
dataTable.Columns.Add("SampleString", typeof(string)); 
dataTable.Columns.Add("SampleInt", typeof(Int32)); 
//and fill in some values 
dataTable.Rows.Add("99", 99); 
dataTable.Rows.Add("98", null); 
dataTable.Rows.Add("97", 99); 

SqlParameter parameter = new SqlParameter(); 
//The parameter for the SP must be of SqlDbType.Structured 
parameter.ParameterName="@Sample"; 
parameter.SqlDbType = System.Data.SqlDbType.Structured; 
parameter.Value = dataTable; 
command.Parameters.Add(parameter); 
31 мар 14, 15:50    [15811933]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6202
FatherSql,

для передачи табличного типа можно использовать не DataTable, а свою обертку, реализующую IEnumerable<SqlDataRecord>. Пример:
CREATE TYPE [dbo].[ut_int_array] AS TABLE(
  [number] [int] NULL
)
GO

public class DbIntArray : List<DbInt>, IEnumerable<SqlDataRecord>
{
  IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
  {
    var res = new SqlDataRecord(new SqlMetaData("number", SqlDbType.Int));
    foreach (var n in this)
    {
      res.SetInt32(0, n.N);
      yield return res;
    }
  }
}

public class DbInt
{
  public int N { get; set; }
}

преимущество такого подхода - строгая типизация (в отличие от DataTable, заворачивающего все значения в object), плюс все возможности IEnumerable<T> (LINQ, yield iterations).
И еще пара нюансов: при передаче табличного типа параметром в табличную функцию или запрос, необходимо указывать имя табличного типа; если передаваемый массив пустой, нужно параметру присваивать значение null, а не DbNull.Value.
31 мар 14, 16:22    [15812151]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
dvim
Member

Откуда: Санкт Петербург
Сообщений: 711
Сон Веры Павловны,
если нужно передать массив - можно поступить старым олдфаговским методом - собрать все параметры в 1 строку и передать - а внутри распарсить.

Ну собственно так делается в 99% случаях.
А вот для 1 процента как раз и идет использование табличных параметров.

Там, где этот список большой и скорость важна
31 мар 14, 17:22    [15812611]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Сон Веры Павловны
можно использовать не DataTable, а свою обертку, реализующую IEnumerable<SqlDataRecord>
Ну можно ещё и DataReader без всяких IEnumerable.
Сон Веры Павловны
преимущество такого подхода - строгая типизация (в отличие от DataTable, заворачивающего все значения в object), плюс все возможности IEnumerable<T> (LINQ, yield iterations).
Что-то как-то сомнительные высказывания на счёт типизации, имхо не то вы вкладываете в это понятие. И возможности "IEnumerable" тоже - мол прям свет в конце тунеля, шож мыж делали без него.

Чисто придирка к получившейся форме подачи.
31 мар 14, 17:25    [15812630]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
XML достаточен в 99.99% случаев.
31 мар 14, 17:50    [15812808]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6202
Mnior
Что-то как-то сомнительные высказывания на счёт типизации, имхо не то вы вкладываете в это понятие.

Что же здесь сомнительного?
var dt = new DataTable();
dt.Columns.Add("fd", typeof (int));
dt.Rows.Add("abc");

- ошибка вылезет только на рантайме.
А вот это просто не cкомпилируется:
var dbArray = new DbIntArray();
dbArray.Add(new DbInt{N=DateTime.Now});

Mnior
И возможности "IEnumerable" тоже - мол прям свет в конце тунеля, шож мыж делали без него.

Крутили бы циклы. И с постоянным тайпкастингом внутри. Да, LINQ - синтаксический сахар, и без него можно обойтись, но он очень сильно облегчает жизнь. И если им можно воспользоваться, то почему бы им не воспользоваться?
dvim
Сон Веры Павловны,
если нужно передать массив - можно поступить старым олдфаговским методом - собрать все параметры в 1 строку и передать - а внутри распарсить.

Ну собственно так делается в 99% случаях.
А вот для 1 процента как раз и идет использование табличных параметров.

Там, где этот список большой и скорость важна

я этим не пользуюсь даже в 1 проценте случаев. Т.е. вообще никогда. Если приходится иметь дело с 2005-м сервером - типизированные коллекции, и их сериализация в xml.
31 мар 14, 17:52    [15812825]     Ответить | Цитировать Сообщить модератору
 Re: Передача массивов в хранимые процедуры  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Сон Веры Павловны
Что же здесь сомнительного?
А вот это просто не cкомпилируется:
var dbArray = new DbIntArray();
dbArray.Add(new DbInt{N=DateTime.Now});
Вот именно - подмен понятий.
Вы говорите про IEnumerable<SqlDataRecord> - и также в рантайме вылетит.
А в типизацию DbIntArray я могу и DataTable всунуть.

Сон Веры Павловны
Крутили бы циклы. И с постоянным тайпкастингом внутри. Да, LINQ - синтаксический сахар, и без него можно обойтись, но он очень сильно облегчает жизнь.
Какая разница, и там и там циклы:
Сон Веры Павловны
public class DbIntArray : List<DbInt>, IEnumerable<SqlDataRecord>
...
    foreach (var n in this)
Какая разница передадут это через ссылку типа IEnumerable или через ссылку в котором будет DataReader. В решении задачи - монописуально.

Не в этом выгода LINQ.

Складывается ощущение или словно слышал звон или что скорее всего, неправильно выразился. Спешка?
31 мар 14, 19:32    [15813313]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить