Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
например есть таблица счетов - допустим [BILL] и в ней записей 10 в клиентском приложении юзер отмечает в гридине например 5 записей хочется иметь процедуру, возвращающую например полную детализацию выбранных записей (детализация - в таблице [BillDetails]) но тогда процедуре надо передавать это множество, состоящее из выбранных записей (их уникальные ID) я нашел вариант CREATE PROCEDURE GetBillDetails IDarr varchar(4000) -- в виде '1,2,5,7,11' AS BEGIN declare SQLStr nvarchar(4000) set SQLstr = N'SELECT B.No, BD.Comment FROM Bill B, BillDetail BD where B.Id IN ('+ IDarr +') AND B.Id=BD.BillId)' exec sp_executesql SQLstr END все работает. НО... не нравится что-то мне такое решение 1) неизвестно есть ли ограничение на количество элементов в "IN (...)" 2) а как быть со скоростью выполнения? может есть другой вариант, более изящный ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 08:41 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
Да, это (через стринг) один из способов. если надо было передать не только ИД записей, а еще атрибуты, то можно воспользоваться временной таблицей с заданным именем или передать таблицу как параметр >1) неизвестно есть ли ограничение на количество элементов в "IN (...)" есть, но по-мойму гораздо больше 10, например 255 >2) а как быть со скоростью выполнения? В здешнем форуме этот вопрос уже обсуждался (название типа "как передать МАССИВ в процедуру") и по-мойму есть даже в статья (название не помню) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 09:06 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
2 olden69: Если у Вас sql2k, напишите функцию, получающую стринг и возвращающую таблицу идентификаторов. Тогда Ваш запрос будет иметь примерно следующий вид: SELECT B.No, BD.Comment FROM Bill B, BillDetail BD where B.Id IN (select id from dbo.ВашаФункция('1,2,5,7,11')) AND B.Id=BD.BillId Если 7.0 и ниже, то можно через хранимую процедуру, если не стошнит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 09:47 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
Возможны варианты. В любом случае динамический запрос тут совсем не нужен. 1. Самый тупой вариант CREATE PROCEDURE GetBillDetails @IDarr varchar(4000) -- в виде '1,2,5,7,11' AS BEGIN SELECT B.No, BD.Comment FROM Bill B, BillDetail BD where @IDarr like '%,'+convert(varchar(10),B.Id)+',%' AND B.Id=BD.BillId END 2. Более продвинутый вариант Это то что предложил MadDog Я бы только писал SELECT B.No, BD.Comment FROM Bill B, BillDetail BD, dbo.ВашаФункция('1,2,5,7,11') as vf where B.Id = vf.id AND B.Id=BD.BillId но это дело вкуса Если что могу выложить текст функции, но там ничего сложного нет, она пишется за 15 минут 3. Самый продвинутый вариант Специально создать таблицу, в которой будет два поля - некий идентификатор набора записей и элемент набора записей. Где-то вставлять в эту таблицу нужные данные, а в процедуру передавать только идентификатор набора записей. Тогда процедура будет выглядеть как CREATE PROCEDURE GetBillDetails @ID int AS BEGIN SELECT B.No, BD.Comment FROM Bill B, BillDetail BD, SpecialTbl s where @ID=s.GroupID and B.Id=s.id AND B.Id=BD.BillId END Наверное есть и другие варианты, думайте ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 10:16 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
2 SergSuper: "дело вкуса" мне вкуснее всего с join-ами: SELECT B.No, BD.Comment FROM Bill B join BillDetail BD on B.Id=BD.BillId join dbo.ВашаФункция('1,2,5,7,11') vf on B.Id = vf.id не хотелось затмевать идею. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 11:48 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
Для этого можно использовать и специальную таблицу как указано выше, но временную. Создается хоть на клиенте, хоть в хранимой процедуре, и из всех запускаемых процедур уровнем ниже она видится и модифицируется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2002, 15:20 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
Присоединяюсь к методу, предложенному AlexSh. Единственное - не стоит рисковать и делать временную таблицу - если ее сделать локальной, то она автоматом удалится при выходе из ХП, ее создавшей. Конечно есть вариант в клиенте посылать в одном скрипте ее создание, заполнение и потом уже выполнение нужной ХП, но это чистой воды геморой и сведение логики на клиента. Если создать глобальную временную таблицу, то возникает проблема множества клиентов - глобальная временная таблица хоть всем и видна, но при рассоединении клиента создавшего ее она честно удаляется. И еще проблем целая пачка. Вообще лучше этими временными таблицами, как и курсорами пользоваться в крайних случаях. Так что легче создать обычную таблицу в БД, в дополнении к нужным полям добавить поле SPID DEFAULT @@SPID, чтобы по сессиям различать, и спокойно ее клиентами заполнять, а в хп обычным запросом тащить, не забывая в WHERE дописывать SPID = @@SPID. Ну и не забывать ее очищать в зависимости от постановки - если данные этой тайбл после выполнения ХП уже не нужны, то очищать ее прямо в ХП, иначе при выходе из режима в клиенте, завершения работы клиента, в хп по несуществующим SPID и т.д. и т.п. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2002, 07:03 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
where @IDarr like '%,'+convert(varchar(10),B.Id)+',%' подходит не для @IDarr типа '1,2,3,4' а для @IDarr типа ',1,2,3,4,' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2002, 13:09 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
насчет временных таблиц да, в данном случае лучше не связываться мона так поступить CREATE PROCEDURE [dbo].[GetUniqueTableName] @UNIQUESTR VARCHAR(255) OUT AS begin DECLARE @UNY uniqueidentifier SET @UNIQUESTR = CONVERT(CHAR(36),NEWID()) SET @UNIQUESTR='['+REPLACE(@UNIQUESTR,'-','')+']' return end затем создаем, заполняем, передаем в процедуру и после удаляем ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2002, 13:26 |
|
||
|
как передать "множество" в процедуру? или другое решение...
|
|||
|---|---|---|---|
|
#18+
2 olden69 Пардон, конечно надо писать так: where ','+@IDarr+',' like '%,'+convert(varchar(10),B.Id)+',%' но я думаю что суть и так понятна была Что касается временных таблиц(ВТ). Во-первых в использование глобальных ВТ я смысла вообще не вижу - вместо того чтобы обходить трудности с проверкой существования их можно просто создать постоянную таблицу. Во-вторых использование неглобальных ВТ для передачи данных это примерно тоже что использование глобальных переменных для передачи параметров в процедуру в процедурных языках - вроде и можно, вроде и работает, но как это ненормально. Например, потом Вы или Ваши коллеги будут смотреть на код процедуры и думать: а что это за таблица, откуда она тут взялась? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.02.2002, 07:16 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32023629&tid=1823764]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
32ms |
get topic data: |
15ms |
get forum data: |
3ms |
get page messages: |
75ms |
get tp. blocked users: |
1ms |
| others: | 252ms |
| total: | 410ms |

| 0 / 0 |
