powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / как передать "множество" в процедуру? или другое решение...
10 сообщений из 10, страница 1 из 1
как передать "множество" в процедуру? или другое решение...
    #32023618
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
например
есть таблица счетов - допустим [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) а как быть со скоростью выполнения?

может есть другой вариант, более изящный ?
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023624
Replicant
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, это (через стринг) один из способов. если надо было передать не только
ИД записей, а еще атрибуты, то можно воспользоваться временной таблицей
с заданным именем или передать таблицу как параметр

>1) неизвестно есть ли ограничение на количество элементов в "IN (...)"

есть, но по-мойму гораздо больше 10, например 255

>2) а как быть со скоростью выполнения?

В здешнем форуме этот вопрос уже обсуждался (название типа "как передать МАССИВ в процедуру")
и по-мойму есть даже в статья (название не помню)
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023629
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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 и ниже, то можно через хранимую процедуру, если не стошнит.
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023635
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможны варианты. В любом случае динамический запрос тут совсем не нужен.

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


Наверное есть и другие варианты, думайте
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023651
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
не хотелось затмевать идею.
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023674
AlexSh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для этого можно использовать и специальную таблицу как указано выше, но временную. Создается хоть на клиенте, хоть в хранимой процедуре, и из всех запускаемых процедур уровнем ниже она видится и модифицируется.
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023704
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Присоединяюсь к методу, предложенному AlexSh. Единственное - не стоит рисковать и делать временную таблицу - если ее сделать локальной, то она автоматом удалится при выходе из ХП, ее создавшей. Конечно есть вариант в клиенте посылать в одном скрипте ее создание, заполнение и потом уже выполнение нужной ХП, но это чистой воды геморой и сведение логики на клиента. Если создать глобальную временную таблицу, то возникает проблема множества клиентов - глобальная временная таблица хоть всем и видна, но при рассоединении клиента создавшего ее она честно удаляется. И еще проблем целая пачка. Вообще лучше этими временными таблицами, как и курсорами пользоваться в крайних случаях. Так что легче создать обычную таблицу в БД, в дополнении к нужным полям добавить поле SPID DEFAULT @@SPID, чтобы по сессиям различать, и спокойно ее клиентами заполнять, а в хп обычным запросом тащить, не забывая в WHERE дописывать SPID = @@SPID. Ну и не забывать ее очищать в зависимости от постановки - если данные этой тайбл после выполнения ХП уже не нужны, то очищать ее прямо в ХП, иначе при выходе из режима в клиенте, завершения работы клиента, в хп по несуществующим SPID и т.д. и т.п.
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023875
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
where @IDarr like '%,'+convert(varchar(10),B.Id)+',%'
подходит не для @IDarr типа '1,2,3,4'
а для @IDarr типа ',1,2,3,4,'
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023876
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
насчет временных таблиц
да, в данном случае лучше не связываться
мона так поступить

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

затем создаем, заполняем, передаем в процедуру и после удаляем
...
Рейтинг: 0 / 0
как передать "множество" в процедуру? или другое решение...
    #32023899
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 olden69
Пардон, конечно надо писать так:
where ','+@IDarr+',' like '%,'+convert(varchar(10),B.Id)+',%'
но я думаю что суть и так понятна была

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

Во-вторых использование неглобальных ВТ для передачи данных это примерно тоже что использование глобальных переменных для передачи параметров в процедуру в процедурных языках - вроде и можно, вроде и работает, но как это ненормально. Например, потом Вы или Ваши коллеги будут смотреть на код процедуры и думать: а что это за таблица, откуда она тут взялась?
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / как передать "множество" в процедуру? или другое решение...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]