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

Откуда: Москва
Сообщений: 215
есть строка. Например:

Нфывафыва;фывафы;123123
фывафывай;фывафывафыв;6546345634

Формат: 1,2,3,4,5 - до бесконечности, возможных полей через точку с запятой.
далее символы char(13) и char(10). И все по новой.

Вобщем надо разобрать такого вида "строку" на:

поле1 поле2 поле3 поле4 ..... полеN
поле1 поле2 поле3 поле4 ..... полеN

Выше приведен результат запроса. Прошу помощи, совсем в тупике...
13 июл 09, 10:23    [7406995]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Поясню, поле1 = набор символов до 1-й запятой, поле2 = набор после 1-й запятой, поле3 = набор после 2-й запятой и т.д.
13 июл 09, 10:26    [7407021]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 27665
load CVS to SQL Server
13 июл 09, 10:42    [7407129]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
skyANA,

Хм.. С чего вы решили, что это выборка из файла?

Все так же выбирается из sql таблицы, просто нужно преобразовать в нужный мне формат.
13 июл 09, 11:25    [7407359]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal, почитайте похожую тему
13 июл 09, 11:37    [7407425]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
vino,

фишка в том, что этот кусок с парсингом будет ещё в 2-х курсорах.... :) Т.е. мой код вначале выбирает один набор значений, по каждому набору значений имеется свой набор значений. И вот те самые значения содержат строку формата:

ххххх;ууууууу;1111111
zzzzzzz;wwwww;33333333
.............
13 июл 09, 11:51    [7407481]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
очень боюсь за сервер и производительность моего кода. Я так понимаю функции типа "найти кол-во символов в строке" нет в t-sql И придецца самому в каждом круге самого вложенного курсора искать кол-во символов перевода строки и от них уже плясать?
13 июл 09, 11:55    [7407508]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Supra93
Member

Откуда:
Сообщений: 8174
Azvaal
Я так понимаю функции типа "найти кол-во символов в строке" нет в t-sql


LEN (Transact-SQL)
String Functions (Transact-SQL)
13 июл 09, 11:59    [7407531]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Supra93
Azvaal
Я так понимаю функции типа "найти кол-во символов в строке" нет в t-sql


LEN (Transact-SQL)
String Functions (Transact-SQL)


ахахаха ))) Не, я конечно не особо умен, но я имел ввиду количество символа "с" в строке, просто имелл ввиду вариабельность этого самого символа :)
13 июл 09, 12:02    [7407547]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Azvaal
очень боюсь за сервер и производительность моего кода.
Правильно боитесь! Сервер не предназначен для обработки информации внутри поля.
Только для поиска строк, удовлетворяющих заданным условиям.
Поэтому с низкой скоростью выполнения Вам придётся смириться, пока Вы не начнёте
каждое значение хранить на своей отдельной строке таблицы, а не в списке через запятую.

Для разбора строк по разделителям очень помогает таблица с последовательными числами.
Такую таблицу можно сджойнить с символами каждой Вашей строки с помощью функции SUBSTRING.
Полученный таким образом dataset использовать в нормальных запросах.
Поиском по форуму можно найти немало подобных примеров.

P.S. А таблицу с числами рекомендую завести не только для данной задачи, а и для многих других.
По крайней мере решения с курсорами в таких случаях курят в сторонке...
13 июл 09, 12:15    [7407624]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
И полезно статью почитать:
Массивы и Списки в SQL Server
13 июл 09, 12:27    [7407699]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
iap,

Так.. Придецца обрисовать задачу более явно.

Комуннальные платежи. Автоматические списания.

Есть классификатор КомПлат

в него входят N-e дифференциальное кол-во классификаторов, в названии которых зашито название Ком.службы. Например: Тепловодоканал, Антены, телефон ... и т.п.

внутри этих классификаторов есть ещё обьекты. счета клиентов, с которых списываются ком.платежи

структура:

Счет(название обьекта)

назначение;лиц.счет;сумма;адрес
назначение;лиц.счет;сумма;адрес
назначение;лиц.счет;сумма;адрес
назначение;лиц.счет;сумма;адрес (большое поле, типа memo (Delphi, в других ненаю как обозначается :))

Нужно по каждой ком.службе сформировать проводку типа:
счет
назначение
адрес
лиц.счет
сумма

счет
назначение
адрес
лиц.счет
сумма

счет
назначение
адрес
лиц.счет
сумма


Так вот по одному счету может быть нскольно адресов... Вот этим и обусловлено все это дикое дробление... Если сварганю все это извращение, то пару часов целого отдела автоматизирую )
13 июл 09, 12:59    [7407906]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
чуток обманул...


счет
назначение
адрес
лиц.счет
сумма
атрибуты ком службы(зашиты в классификатор)
13 июл 09, 13:01    [7407914]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal
...Комуннальные платежи. Автоматические списания...

это очередной велосипед?!
Azvaal
...большое поле, типа memo...

в принципе, в той теме, что я дал, все ссылки есть, в том числе и на Массивы и Списки в SQL.
Мысль простая - либо пердоставляете серверу данные в автораспознаваемых форматах (типа XML), либо используете механизм вроде BULK INSERT, как указал skyANA, либо, как в той теме, забрасываете построчно или там же разбиваете на поля.
У вас может быть огромная проблема с проверкой корректности этих списков, т.е. делать это должен клиент до передачи серверу
13 июл 09, 13:41    [7408265]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
iap,


автор
iap Member

Откуда: Москва
Сообщений: 9870 DECLARE @S VARCHAR(100);
SET @S='ertt,ertert,trtqe,werwete,terte,rtert,fffs';

WITH Commas(N,Pos) AS
(
SELECT ROW_NUMBER() OVER(ORDER BY number), number
FROM master.dbo.spt_values
WHERE type='P' AND number BETWEEN 1 AND LEN(@S) AND SUBSTRING(@S,number,1)=','
)
SELECT SUBSTRING(@S,(SELECT Pos+1 FROM Commas WHERE N=4),(SELECT Pos FROM Commas WHERE N=5)-(SELECT Pos+1 FROM Commas WHERE N=4));


автор
Azvaal
Чем лучше?

Тем, что это стандарт. Не придётся переписывать при смене версии сервера.
Обращение напрямую к системным объектам - моветон. IMHO
13 июл 09, 13:41    [7408268]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
автор
Azvaal
Member

Откуда: Мегион
Сообщений: 91 Azvaal,

нашёл, то что искал

select [name] from [syscolumns] where [id]=(select [id] FROM [sysobjects] where [name] = 'Имя таблицы') order by colid


автор
iap
Member

Откуда: Москва
Сообщений: 9870 Azvaal
Glory,

ну да, ну да, в общем, я хотел получить именно это

В таком случае лучше
INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME


автор
Azvaal
Member

Откуда: Мегион
Сообщений: 91 Чем лучше?


автор
iap
Member

Откуда: Москва
Сообщений: 9870 Azvaal
Чем лучше?

Тем, что это стандарт. Не придётся переписывать при смене версии сервера.
Обращение напрямую к системным объектам - моветон. IMHO
13 июл 09, 13:43    [7408295]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
или там же разбиваете на строки (я бы сделал попутно разбивке на поля).
ЗЫ: очевидно, задача резко упрощается, когда поля фиксированной длины, может этого можно добиться на клиенте? Ведь он все-равно парсит-строит этот текст
13 июл 09, 13:44    [7408311]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
vino,

Дорогой друг. Я собственноручно забиваю классификаторы.

Блин, я вроде и сам уже понимать начинаю, что обьясняю, а это обычно последняя стадия ))

Вобщем так: я забил Ком. Службу ТВК (тепловодоканал). В классификаторе (его атрибутах) забиваю данные о самой компании.

далее в классификатор ТВК добавляю обьект. Нажатием кнопки insert вызывается форма с 1 edit и 1 memo полями. В edit пишу 40817................01 (счет клиента).

В memo забиваю:

за гор воду;123445;1000.50;Ленина 14а, 168, звонок номер два (шутка...)
за гор воду;666111;1000.50;Ленина 14а, 168, звонок номер один (шутка...)

мой запрос открывает курсор со списком классификаторов-компаний (работа по каждой компании)
далее в нем открывает 2-й курсор со списком счетов клиентов (работа по каждому обьекту-счету)

и вот теперь уже я начинаю работать с полем memo

из него мне нужно сформировать таблицу типа

Kompany ClientSchet Purpose LicSchet Summ Address

ТВК 40817...01 за гор в. 123445 1000.50 ............ 2

ТВК 40817...01 за гор в. 666111 1000.50 ............ 1
13 июл 09, 13:55    [7408427]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Azvaal
В memo забиваю:

за гор воду;123445;1000.50;Ленина 14а, 168, звонок номер два (шутка...)
за гор воду;666111;1000.50;Ленина 14а, 168, звонок номер один (шутка...)
Сделали бы Вы этот самый "разбор строки" на клиенте до отправки данных на сервер, что ле...
13 июл 09, 14:02    [7408488]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Senya_L,

ой ешкин кот.....

я сегодня добавляю классификатор, в него обьекты. Посредсвтвом этого на сервере заполняются таблицы

После, раз в месяц юзер будет запускать отчет, который посредством моего кода будет разбирать это чертово memo поле и формировать текстовый файл для последущей обработки...
13 июл 09, 14:06    [7408519]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
create table #ID
(ID numeric(15,0))
create table #REST
(ResourceID    numeric(15,0)
,InstOwnerID numeric(15,0)
,Brief         varchar(20)
,Qty           money)
create table #END
(Summ          money
,Debet         varchar(20)
,Kredit        varchar(20)
,RasSchet      varchar(20)
,MFO           varchar(9)
,NameRcv       varchar(255)
,Prim3         varchar(255)
,LicSchet      varchar(10)
,Prim5         varchar(10)
,Komm          money
,ResourceID    numeric(15,0)
,InstOwnerID   numeric(15,0))

declare @DateRep varchar(10)
select @DateRep='20090514'--%ArcDay!

insert #ID
select 2010003353854/*
union all
select 2010003353853
select dm.ID
  from tDocMark dm
 where dm.SPID = @@spid
*/
insert #REST
select dt2.ResourcePsvID, r2.InstOwnerID, r2.Brief, dt2.FixQty
  from #ID           id
      ,tDealTransact dt
      ,tDealTransact dt2
      ,tResource     r
      ,tResource     r2
 where dt.DealTransactID = id.ID
   and dt.Date           = @DateRep--'20090514'
   and dt2.DocNumber     = dt.DocNumber
   and dt2.Date          = @DateRep--'20090514'
   and r.ResourceID      = dt2.ResourceID
   and r.Brief like '47422%'
   and r2.ResourceID     = dt2.ResourcePsvID

delete #REST
  from #REST
 where #REST.ResourceID not in
(
select distinct ocr.ObjectID
  from tOBjClassifier oc
      ,tOBjClsRelation ocr
 where oc.ParentID         = 2010000010821
   and ocr.ObjClassifierID = 2010000010892--oc.ObjClassifierID
)
select * from #REST
drop table #ID
drop table #REST
drop table #END
--=========================================================
   DECLARE CMark CURSOR SCROLL
   for 
    select ObjClassifierID, Name
      from tObjClassifier  oc
     where oc.ParentID = 2010000010821
   
   open CMark
   
   declare @ID   numeric(15,0)
          ,@Name varchar(255)
                                           
   fetch first
   from CMark
   into @ID, @Name
   
   -- ????
   while @@FETCH_STATUS = 0
   begin

insert #END
select isnull(convert(money, replace(substring(ocr.Comment,1,charindex(';',ocr.Comment,0)-1),',','.')),0) as Summ
      ,rt.Brief      as Debet
      ,oc.Descr      as Kredit
      ,oc.Param      as RasSchet
      ,oc.Comment    as MFO
      ,oc.Name       as NameRcv
      ,isnull(substring(ocr.Comment
                 ,charindex(';',ocr.Comment,charindex(';',ocr.Comment,0)+1)+1
                 ,len(ocr.Comment)+1),'') as Prim3
      ,isnull(substring(ocr.Comment
                 ,charindex(';',ocr.Comment)+1
                 ,charindex(';',ocr.Comment,charindex(';',ocr.Comment)+1)-1-charindex(';',ocr.Comment)),'')  as LicSchet
      ,substring(oc.Brief,1,3)            as Prim5
      ,0
      ,rt.ResourceID
      ,rt.InstOwnerID
  from #REST           rt
      ,tOBjClsRelation ocr
      ,tObjClassifier  oc
 where ocr.ObjectID        = rt.ResourceID         
   and ocr.ObjClassifierID = @ID
   and oc.ObjClassifierID  = ocr.ObjClassifierID

update #END
set #END.Komm = case
                  when (select sum(e.Komm)
                          from #END e
                         where e.ResourceID = #END.ResourceID) = 0
                    then 
                      case
                        when (select 1
                                from #END e
                               where e.ResourceID = #END.ResourceID
                                 and e.Prim5 = 'ТЭК') <> '' then 20
                        else 15
                    end
                  when (select sum(e.Komm)
                          from #END e
                         where e.ResourceID = #END.ResourceID) = 15
                    then 
                      case
                        when (select 1
                                from #END e
                               where e.ResourceID = #END.ResourceID
                                 and e.Prim5 = 'ТЭК') <> '' then 35
                        else #END.Komm
                    end
                  when (select sum(e.Komm)
                          from #END e
                         where e.ResourceID = #END.ResourceID) = 20
                    then 
                      case
                        when (select 1
                                from #END e
                               where e.ResourceID = #END.ResourceID
                                 and e.Prim5 = 'ТЭК') = '' then #END.Komm
                        else 35
                    end
                  else #END.Komm
                end
  from #END
      ,#REST rt
 where rt.ResourceID = #END.ResourceID
   and #END.NameRcv  = @Name

update #END
set #END.Komm = case
                  when (select 1
                          from #END e
                         where e.ResourceID = #END.ResourceID
                           and e.Komm       = 35) = 1 then 0
                  else #END.Komm
                end
  from #END
      ,#REST rt
 where rt.ResourceID = #END.ResourceID
   and #END.Komm     < 35

update #END
set #END.Summ = case
                  when (#END.Summ+#END.Komm)>rt.Qty then 0
                  else #END.Summ
                end
   ,#END.Komm = case
                  when (#END.Summ+#END.Komm)>rt.Qty then 0
                  else #END.Komm
                end
  from #END
      ,#REST rt
 where rt.ResourceID = #END.ResourceID
   and #END.NameRcv  = @Name

update #REST
set #REST.Qty = case
                  when (e.Summ+e.Komm)>#REST.Qty then #REST.Qty
                  else #REST.Qty-(e.Summ+e.Komm)
                end
  from #REST
      ,#END e
 where e.ResourceID = #REST.ResourceID
   and e.NameRcv  = @Name

    FETCH NEXT
    from CMark
    into @ID, @Name
   end
        
   CLOSE CMark
   DEALLOCATE CMark

delete #END
from #END
where Summ = 0

select e.*
      ,(i.Name+' '+i.Name1+' '+i.Name2) as Name
      ,ia.Name as Address
      ,Flag = case
                when patindex('\%[^0-9]\%',e.Prim5)<>0 then 1
                else 0
              end
      ,DateRep = convert(datetime,@DateRep)
  from #END         e
      ,tInstitution i
      ,tInstAddress ia
 where i.InstitutionID  = e.InstOwnerID
   and ia.InstitutionID = i.InstitutionID
   and ia.AddressTypeID = 5
--select * from #REST
   
drop table #ID
drop table #REST
drop table #END

Достали ))))))))
13 июл 09, 14:13    [7408572]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
такой код разбирает "строку", но если в memo только одна СТРОКА, т.е. нет char(10) & char(13)

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

Для этого мне требуется переписать код. Отчет итак вешал сервак, на котором работаю СОВСЕМ не я один.. Теперь же, если я добавлю ещё один курсор + Цикл он вообще нафиГ рухнет к чертям. Не особо этого хочется )))
13 июл 09, 14:18    [7408603]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Конечно можно добавить индексы, но не думаю, что это особо спасет ситуацию.. Намутил я грешный черт знает что...
13 июл 09, 14:21    [7408626]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Azvaal
Senya_L,

ой ешкин кот.....
Ой, мляяя!..
Это вот что по-Вашему?
автор
за гор воду;123445;1000.50;Ленина 14а, 168, звонок номер два (шутка...)
за гор воду;666111;1000.50;Ленина 14а, 168, звонок номер один (шутка...)
Это таблица (отношение, реляция), которое Вы пытаетесь впихнуть в одно! поле типа varchar. Вы стряпаете ненормализованную таблицы, а потом стенаете, что "еще один курсор добьет сервер". В ветке "Проектирование БД" Вас бы распяли. И поделом.

ЗЫ. Ну хочется Вам одно поле, так Вы его хоть ХМL-ным сделайте. Хоть индексы работоспособные можно будет приладить...
13 июл 09, 14:30    [7408712]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Senya_L,

Diasoft - Вам говорит о чем-нибудь это слово?

Если да, сочувствую...

Если нет - ВОЗРАДУЙТЕСЬ!!!
13 июл 09, 14:36    [7408769]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить