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

Откуда:
Сообщений: 298
входым параметром процедуры является строковая переменная @listnum, ее примерное содержание '4,7,13,67' - значения поля, которые нужно выбирать
эта переменная учавствует запросе курсора
    DECLARE CRS1 CURSOR LOCAL STATIC FOR
		select s.number from panelSpec S where s.id=@ID and s.number in (@listnum)
	OPEN CRS1
	FETCH NEXT FROM CRS1 INTO @numb

при выполнении выдает ошибку, что не может строку перевести в число

как верно реализовать запрос?
6 авг 09, 16:22    [7506926]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
динамический скл
-------------------------------------
Jedem Das Seine
6 авг 09, 16:24    [7506937]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Массивы и Списки в SQL Server
6 авг 09, 16:25    [7506940]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Slider_spb
Member

Откуда:
Сообщений: 800
На основе материала "Массивы и списки в SQL сервер была создана функуция:
CREATE FUNCTION dbo.fnSplitToINT(@tstr varchar(8000), @Delimiter char(1) = ',')
RETURNS @List TABLE (listpos int NOT NULL, ListVal int NOT NULL)
AS
BEGIN
DECLARE @pos      int,
        @textpos  int,
        @chunklen smallint,
        @str      varchar(8000),
        @tmpstr   varchar(8000),
        @leftover varchar(8000),
        @sCount   int

  SET @sCount = 0
  SET @textpos = 1
  SET @leftover = ''
  IF LEN(@tstr) = 1 SET @tstr = @tstr + @Delimiter
  WHILE @textpos <= datalength(@tstr) / 2
  BEGIN
    SET @chunklen = 4000 - datalength(@leftover) / 2
    SET @tmpstr = ltrim(@leftover + substring(@tstr, @textpos, @chunklen))
    SET @textpos = @textpos + @chunklen

    SET @pos = charindex(@Delimiter, @tmpstr)
    WHILE @pos > 0
    BEGIN
      SET @sCount = @sCount + 1
      SET @str = substring(@tmpstr, 1, @pos - 1)
      INSERT @List(listpos, ListVal) VALUES(@sCount, convert(int, @str))
      SET @tmpstr = ltrim(substring(@tmpstr, @pos + 1, len(@tmpstr)))
      SET @pos = charindex(@Delimiter, @tmpstr)
    END
    SET @leftover = @tmpstr
  END
  IF ltrim(rtrim(@leftover)) <> ''
    INSERT @List(listpos, ListVal) VALUES(@sCount + 1, convert(int,@leftover))
RETURN
END
В создав её, ваш курсор будет выглядеть так:
DECLARE CRS1 CURSOR LOCAL STATIC FOR
		select s.number from panelSpec S where s.id=@ID and s.number in
 (SELECT ListVal FROM dbo.fnSplitToINT(@listnum, DEFAULT))
	OPEN CRS1
	FETCH NEXT FROM CRS1 INTO @numb
6 авг 09, 16:46    [7507100]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
а нужел ли вообще здесь курсор ?
-------------------------------------
Jedem Das Seine
6 авг 09, 16:47    [7507106]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
amandra
Member

Откуда:
Сообщений: 298
Maxx
а нужел ли вообще здесь курсор ?
-------------------------------------
Jedem Das Seine

да, внутри него разбиратся данные
6 авг 09, 16:51    [7507137]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
amandra
Member

Откуда:
Сообщений: 298
Slider_spb
На основе материала "Массивы и списки в SQL сервер была создана функуция:
CREATE FUNCTION dbo.fnSplitToINT(@tstr varchar(8000), @Delimiter char(1) = ',')
RETURNS @List TABLE (listpos int NOT NULL, ListVal int NOT NULL)
AS
BEGIN
DECLARE @pos      int,
        @textpos  int,
        @chunklen smallint,
        @str      varchar(8000),
        @tmpstr   varchar(8000),
        @leftover varchar(8000),
        @sCount   int

  SET @sCount = 0
  SET @textpos = 1
  SET @leftover = ''
  IF LEN(@tstr) = 1 SET @tstr = @tstr + @Delimiter
  WHILE @textpos <= datalength(@tstr) / 2
  BEGIN
    SET @chunklen = 4000 - datalength(@leftover) / 2
    SET @tmpstr = ltrim(@leftover + substring(@tstr, @textpos, @chunklen))
    SET @textpos = @textpos + @chunklen

    SET @pos = charindex(@Delimiter, @tmpstr)
    WHILE @pos > 0
    BEGIN
      SET @sCount = @sCount + 1
      SET @str = substring(@tmpstr, 1, @pos - 1)
      INSERT @List(listpos, ListVal) VALUES(@sCount, convert(int, @str))
      SET @tmpstr = ltrim(substring(@tmpstr, @pos + 1, len(@tmpstr)))
      SET @pos = charindex(@Delimiter, @tmpstr)
    END
    SET @leftover = @tmpstr
  END
  IF ltrim(rtrim(@leftover)) <> ''
    INSERT @List(listpos, ListVal) VALUES(@sCount + 1, convert(int,@leftover))
RETURN
END
В создав её, ваш курсор будет выглядеть так:
DECLARE CRS1 CURSOR LOCAL STATIC FOR
		select s.number from panelSpec S where s.id=@ID and s.number in
 (SELECT ListVal FROM dbo.fnSplitToINT(@listnum, DEFAULT))
	OPEN CRS1
	FETCH NEXT FROM CRS1 INTO @numb

спасибо, как раз то что нужно...
список разобран во временную таблицу и на основе данных из нее строится запрос...гемор, но другого выхода нет :)
спасибо
6 авг 09, 16:56    [7507195]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Mayh
Guest
Зачем писать огромную функцию и затем использовать курсор?

Загоните динамическим запросом данные во временную таблицу и обрабатывайте её в цикле.
6 авг 09, 16:56    [7507200]     Ответить | Цитировать Сообщить модератору
 Re: динамический параметр запроса  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
amandra
входым параметром процедуры является строковая переменная @listnum, ее примерное содержание '4,7,13,67' - значения поля, которые нужно выбирать
эта переменная учавствует запросе курсора
    DECLARE CRS1 CURSOR LOCAL STATIC FOR
		select s.number from panelSpec S where s.id=@ID and s.number in (@listnum)
	OPEN CRS1
	FETCH NEXT FROM CRS1 INTO @numb

при выполнении выдает ошибку, что не может строку перевести в число

как верно реализовать запрос?


как вариант:
DECLARE CRS1 CURSOR LOCAL STATIC FOR
	select s.number from panelSpec S where s.id=@ID and s.number in (
			SELECT
				cast(substring(s,i+1,charindex(',',s+',',i+1)-i-1) as int)
			FROM(
				SELECT 
					row_number() OVER(ORDER BY a.i) i
				FROM
					(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) a
					,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) b
					,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) c
				) a
				,(SELECT ','+@listnum s)b
			WHERE
				substring(s,i,1)=','
			)
OPEN CRS1
FETCH NEXT FROM CRS1 INTO @numb
6 авг 09, 17:47    [7507541]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить