Передача параметра в ХП

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Передача параметра в ХП

Сообщение VVitafresh » 21.12.2006 (Чт) 15:11

Можно ли реализовать вызов процедуры, чтобы параметр подставлялся в условие IN (@varname)?

Например создаем процедуру (которая не работает как надо):
Код: Выделить всё
Create Proc v_test1 (
   @varname  varchar(25)
                    )
As
  Begin

  SELECT *
  FROM Table1
  WHERE field_name IN (@varname)
end


Нужно чтобы при вызове:
Код: Выделить всё
execute v_test1 "'1','2','3'"


Получили выборку:
Код: Выделить всё
SELECT * from Table1 WHERE field_name IN ('1','2','3')


Реализовать нужно на Transact-SQL (Sybase или MS SQL). Возможно это, или не получится?
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.12.2006 (Чт) 15:15

Ну ты можешь сделать SET @sql = 'SELECT ... IN ('+@varname+')', а затем EXECUTE(@sql). Но вообще, лучше пересмотреть логику.
Lasciate ogni speranza, voi ch'entrate.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 21.12.2006 (Чт) 15:26

Код: Выделить всё
declare @s varchar(1000)
declare @sql nvarchar(4000)

set @s='51,53'
set @s='select * from clients where clientid in('+@s+')'
set @sql=convert(nvarchar(4000),@s)

exec sp_executesql @sql

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.12.2006 (Чт) 15:36

Konst_One, а зачем так сложно? Или в 2005 иначе нельзя?
Lasciate ogni speranza, voi ch'entrate.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 21.12.2006 (Чт) 15:40

в 2005 может и можно, я для Sql2000 написал

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 21.12.2006 (Чт) 15:55

Спасибо за подсказку с простым SELECT'ом работает, а можно ли это реализовать при открытии курсора
Код: Выделить всё
declare v_cur1 cursor for select ... from dbo.tablename     
  where parametr in (@varname)   

alibek писал(а):Но вообще, лучше пересмотреть логику.

Даже не знаю как изменить логику :roll:
Из VB-шной программы передается с десяток признаков, по которым нужно отбирать записи из таблицы и дальше обрабатывать в ХП. Эти признаки очень удобно перечислить через запятую и отбирать из таблицы через IN (...) А как можно сделать по-другому?
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 21.12.2006 (Чт) 15:58

не уверен, что такое возможно

как вариант:создать выборку во временной таблице, а курсор уже открывать на ее основе

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 21.12.2006 (Чт) 16:16

Пока я вижу только вариант с созданием временной таблицы, заполнением ее нужными значениями и последующим объявлением курсора:
Код: Выделить всё
declare v_cur1 cursor FOR SELECT ... FROM dbo.tablename 
  WHERE parametr IN (SELECT parametr from #tmp_table)

Но может быть возможны другие способы...

[Добавлено]Хе-хе, Konst_One добавил приписку быстрее, чем я успел запостить.[/Добавлено]
Последний раз редактировалось VVitafresh 21.12.2006 (Чт) 16:19, всего редактировалось 1 раз.
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.12.2006 (Чт) 16:25

А зачем тебе #tmp_table?
Если она не слишком большая, то DECLARE @tmp_table TABLE (fld1 int) ИМХО удобнее.
Lasciate ogni speranza, voi ch'entrate.

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 21.12.2006 (Чт) 16:29

alibek писал(а): DECLARE @tmp_table TABLE (fld1 int) ИМХО удобнее.

По-моему, в Sybase'e так нельзя делать, поэтому CREATE TABLE #tablename ...
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Сообщение HandKot » 22.12.2006 (Пт) 10:07

если текстовое поле
Код: Выделить всё
SELECT * FROM Table1 WHERE CHARINDEX(','+field_name+',',@varname) <> 0


вызов

Код: Выделить всё
execute v_test1 ",1,2,3,"
I Have Nine Lives You Have One Only
THINK!

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 22.12.2006 (Пт) 10:32

HandKot, сейчас под рукой нет MS SQL чтобы проверить, но судя по http://msdn2.microsoft.com/en-us/library/ms186323.aspx charindex в данном случае не подходит (или ты не правильно понял вопрос).
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Сообщение HandKot » 22.12.2006 (Пт) 13:56

VVitafresh писал(а):HandKot, сейчас под рукой нет MS SQL чтобы проверить, но судя по http://msdn2.microsoft.com/en-us/library/ms186323.aspx charindex в данном случае не подходит (или ты не правильно понял вопрос).


может вопрос не понял
я понял так, выбрать все записи из таблицы TABLE, для которых верно условие, что поле Field1 принимает одно из значений, записанных в строку
или задача совсем в другом?

ЗЫЖ
на MS SQL все отрабатывает
Код: Выделить всё
declare @varname varchar(100)
set @varname = ',1,22,'
select * from (
   select 1 as [f1], '1' as [f2]
   union ALL
   select 2, '2'
   union ALL
   select 3, '3'
   union ALL
   select 10, '10'
   union ALL
   select 11, '11'
   union ALL
   select 22, '22'
   union ALL
   select 11, '11'
   union ALL
   select 33, '33'
) A
where CHARINDEX(','+f2+',', @varname)<> 0

возвращает
записи
Код: Выделить всё
1   1
22   22
I Have Nine Lives You Have One Only
THINK!

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 23.12.2006 (Сб) 21:56

Наконец добрался до MS SQL.
HandKot, да ты прав. CHARINDEX делает именно то, что мне нужно. Это я недопонял. И, главное, в Sybase тоже есть эта функция.

Только объясни мне еще, зачем при вызове в параметре ",1,2,3," первая и последняя запятая? По-моему, и без них все замечательно работает.
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 25.12.2006 (Пн) 8:29

Для того, чтобы случайных совпадений избежать.
Lasciate ogni speranza, voi ch'entrate.

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Сообщение HandKot » 25.12.2006 (Пн) 8:47

VVitafresh писал(а):Только объясни мне еще, зачем при вызове в параметре ",1,2,3," первая и последняя запятая? По-моему, и без них все замечательно работает.

alibek прав

ЗЫЖ ИМХО вместо "запятой" лучше использовать другой разделитель
I Have Nine Lives You Have One Only
THINK!

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 25.12.2006 (Пн) 11:59

alibek писал(а):Для того, чтобы случайных совпадений избежать.

Можно наглядный пример, как первая и последяя запятая в параметре помогает избежать случайных совпадений?

Чёт никак не могу придумать :roll:
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 25.12.2006 (Пн) 12:17

",1," ищет 1
если же искать "1" то тогда 111 тоже попадет

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 25.12.2006 (Пн) 12:55

Понятно.
А я мыслил ограниченно в рамках своей задачи, где у меня размерность текстового поля char(1).
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 25.12.2006 (Пн) 13:03

Для такого случая можно значительно упростить.
CHARINDEX(@char,@allowedchars)>0
Lasciate ogni speranza, voi ch'entrate.

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 25.12.2006 (Пн) 13:05

Что я и сделал :)
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList