Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.12.26;
Скачать: CL | DM;

Вниз

Как преобразовать строку "123" в "1,2,3" в MS SQL 2005   Найти похожие ветки 

 
И. Павел ©   (2010-09-17 15:31) [0]

Здравствуйте.

В таблице MS SQL 2007 есть поле, содержащее строку десятичных цифр.
Мне нужно разбить его таким образом:
исходная строка "479"
конечная строка "4,7,9"
чтобы можно было вставить ее в SQL запрос: "AND date_type IN (4, 7, 9)"
Можно, конечно, хранимую процедуру писать (проходим все символы c сперпоследнего влево, ставим запятую и сдвигаем правую часть на единицу вправо), но может есть уже что-то готовое для таких случаев?

Подскажите, пожалуйста, можно ли использовать такую входную строку цифр в операции IN, используя стандартные средства?

Заранее спасибо.


 
И. Павел ©   (2010-09-17 15:31) [1]

Опечатался: MS SQL 2007 -> MS SQL 2005


 
И. Павел ©   (2010-09-17 15:34) [2]

Ну вот, долго ничего в голову не приходило и коллеги не могли подсказать, а как написал вопрос на форуме - дошло, что IN можно заменить на pos, осталось только его в MS SQL найти. Извиняюсь за беспокойство.


 
Anatoly Podgoretsky ©   (2010-09-17 15:42) [3]

> И. Павел  (17.09.2010 15:34:02)  [2]

MSSQL поддерживает for и полный спектр работы со строками.


 
И. Павел ©   (2010-09-17 15:50) [4]

> MSSQL поддерживает for и полный спектр работы со строками.

Нашел: CHARINDEX.


 
12 ©   (2010-09-17 15:56) [5]

и чем он поможет? Зацепок то нет
>исходная строка "479"
>конечная строка "4,7,9"


 
И. Павел ©   (2010-09-17 15:59) [6]

> и чем он поможет? Зацепок то нет

А я напишу так:
WHERE (data_type = 1) AND (CHARINDEX("1", typestr) != 0) OR (data_type = 2) AND (CHARINDEX("2", typestr) != 0) OR ...
Т.к. тут нет операций сдвига строки (как было бы в хранимой процедуре), думаю даже 9 таких условий будут работать побыстрее.


 
12 ©   (2010-09-17 16:05) [7]

может, нужно банально зпт наствить?

declare @i int
declare @S varchar(10), @S2 varchar(20)
set @S = "12345"
set @s2 = ""
set @i = 1
while(@i < LEN(@S)+1)
begin
 set @S2 = @S2 + SUBSTRING(@S,@i,1)+","
 set @i = @i + 1
end
select SUBSTRING(@S2,1,len(@s2)-1)


 
Ega23 ©   (2010-09-17 16:21) [8]


> думаю даже 9 таких условий будут работать побыстрее.

Спорно. Я бы так, как 12 ©   (17.09.10 16:05) [7] сделал.
Только LEN(@S) +1 сначала вычислил бы, @s2 проинициализировал как "-1", а запятую добавлял бы перед. Ну set @S2 = @S2 + "," + SUBSTRING(@S,@i,1)

А с CharIndex - у тебя 10 проходов по исходной строке.


 
картман ©   (2010-09-17 17:06) [9]

не в курсе, как t-sql работает со строками, там, внутрях у себя, но, если как дельфи, то
> WHERE (data_type = 1) AND (CHARINDEX("1", typestr) != 0)
> OR (data_type = 2) AND (CHARINDEX("2", typestr) != 0) OR
>

будет явно быстрее


 
Ega23 ©   (2010-09-17 17:07) [10]


> будет явно быстрее


Да щаз. Ты 10 раз Pos вызываешь против одного прохода по строке.


 
картман ©   (2010-09-17 17:11) [11]


> вызываешь против одного прохода по строке.

с десятью выделениями памяти для новой строки


 
картман ©   (2010-09-17 17:15) [12]

и вообще, так нельзя:
set @s="1,2"
select * from table where id in (@s)
не делать же executeSQL


 
Ega23 ©   (2010-09-17 17:17) [13]


> с десятью выделениями памяти для новой строки

выдели @S2 char(19) и умри от счастья.

> не делать же executeSQL

Сплошь и рядом.


 
картман ©   (2010-09-17 17:23) [14]


> выдели @S2 char(19) и умри от счастья.

ну и будет столько-то перезаписей, а как они делаются, тоже вопрос.


>
> > не делать же executeSQL
>
> Сплошь и рядом.


ну, тогда как бы смысл экономии пары тактов пропадает


 
И. Павел ©   (2010-09-17 18:05) [15]

Всем спасибо. В понедельник попробую обеими способами - что будет быстрее, то и оставлю.


 
Anatoly Podgoretsky ©   (2010-09-17 18:35) [16]

> Ega23  (17.09.2010 17:07:10)  [10]

Один проход по строке делается или с помощью for , или с помощью while


 
vuk ©   (2010-09-18 00:17) [17]

Я бы делал иначе. Вместо строки типа "1,2,3" я свалил бы коды во временную табличку и дальше её join с полем date_type.


>
> declare @str varchar(50), @i int
> declare @tmp table (date_type int)
>
> select @str = "123"
>
> select @i = 1
> while @i <= len(@str)
> begin
>  insert into @tmp(date_type)
>   select
>    substring(@str, @i, 1)
>   select @i = @i + 1
> end
>
> select
> ...
> from
>  Some_Table tbl join
>  @tmp t on tmp.date_type = tbl.date_type

В принципе, из цикла, разбивающего строку можно сделать UDF, возвращающую таблицу. Тогда запрос сведется к объединению с UDF:


> select
> ...
> from
>  Some_Table tbl join
>  MyUDF("123") t on tmp.date_type = tbl.date_type


 
vuk ©   (2010-09-18 00:18) [18]

В join-ах очепятка:
Вместо
>tmp.date_type = tbl.date_type
должно быть

>t.date_type = tbl.date_type



Страницы: 1 вся ветка

Текущий архив: 2010.12.26;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.009 c
2-1285737249
ruslan_as
2010-09-29 09:14
2010.12.26
Как начать считывать текстовый файл с нужной строки


2-1286078679
mdel
2010-10-03 08:04
2010.12.26
юникод в delphi7


15-1284430430
AlexDn
2010-09-14 06:13
2010.12.26
PayPal


15-1284305392
oxffff
2010-09-12 19:29
2010.12.26
Сходил за грибами и встретил медвежонка


15-1284634047
Kerk
2010-09-16 14:47
2010.12.26
Обладателям девайсов на Android