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

Откуда: Москва
Сообщений: 215
Senya_L
[quot Azvaal]Senya_L,
Вы стряпаете ненормализованную таблицы, а потом стенаете, что "еще один курсор добьет сервер". В ветке "Проектирование БД" Вас бы распяли. И поделом.

ЗЫ. Ну хочется Вам одно поле, так Вы его хоть ХМL-ным сделайте. Хоть индексы работоспособные можно будет приладить...


Клиент сделан не мной. Таблицы спроектированы не мной. Архитектура БД спроектирована не мной.

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

Откуда:
Сообщений: 1191
Azvaal
...В 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

Ведь здесь не надо "плясать" от справочников, разберите код на составляющие, а к нему привяжите справочники без всяких циклов - это будет достаточно быстро.
К тому же порядок полей, очевидно, строгий и их всего 4 - фиксировано:
1) признак компании (никаких знаков препинания?)
2) код клиента
3) сумма
4) остальное (как бы адрес :))
Это одной функцией с одним-двумя циклами можно распарсить в набор строк. А дальше вяжите его с чем хотите.
Про XML уже не раз сказано. Вы тему читали, которую я предложил?
13 июл 09, 14:45    [7408860]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Azvaal
Клиент сделан не мной. Таблицы спроектированы не мной. Архитектура БД спроектирована не мной.
Так обратитесь в этот самый Диасофт и пусть они свое непотребство сами разгребают. Вы же лицензированным софтом пользуетесь? Техподдержку вам должны оказывать? Вот пусть оказывают. Ну это скорее риторика.

А по существу проблемы... Если имеете право свои таблицы добавлять - добавьте дополнительную нормализованную табличку адресов, а уж туда и складывайте нормальные разбитые записи и по ним делайте поиск. Или как вариант - XML-столбец. Разбиение делаете, например, в триггере. Если массивных вставок не ожидается в основную таблицу, то это не очень напряжно сделать разбор на сервер, а для существующих записей - однократно в курсоре.

Поймите одну простую вещь. По таким полям ни один индекс не поможет и вы будете получать обычнй table scan.
13 июл 09, 14:47    [7408887]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal, преимущество однопроходного парсинга в функции с выдачей готового набора строк в том, что charindex имеет третий параметр, которым можно будет воспользоваться и синтаксис текста можно будет чуть проверить...
13 июл 09, 14:53    [7408951]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

читал :)

простой метод поиск+отсечение строки.. Паскаль, пузырьковый метод поиска чем-то напоминает.. Эх, школа...

А вот про разбиение кода на куски я что-то не допетрил... Конкретнее по моему можно хотя бы образно сказать?
13 июл 09, 14:56    [7408984]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

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

читал :)

простой метод поиск+отсечение строки.. Паскаль, пузырьковый метод поиска чем-то напоминает.. Эх, школа...

А вот про разбиение кода на куски я что-то не допетрил... Конкретнее по моему можно хотя бы образно сказать?
Что конкретнее Вам расскзать? Как найти три символа ";" в строки и вырезать из строки 4 фрагмента с помощью SUBSTRING?
13 июл 09, 15:00    [7409015]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

Ведь здесь не надо "плясать" от справочников, разберите код на составляющие, а к нему привяжите справочники без всяких циклов - это будет достаточно быстро.


Я вот про эту фразу :)
13 июл 09, 15:02    [7409030]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

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

Ведь здесь не надо "плясать" от справочников, разберите код на составляющие, а к нему привяжите справочники без всяких циклов - это будет достаточно быстро.


Я вот про эту фразу :)
Смотрим в примерных данных Ваших
автор
ТВК 40817...01 за гор в. 123445 1000.50 ............ 2

ТВК 40817...01 за гор в. 666111 1000.50 ............ 1
Жирным выделены повторы. Разве не требуется (при нормальном проектировании, ессьно) вынести это добро в справочник?

Позовите на помощь человека, разбирающегося в проектировании и НФ в частности.
13 июл 09, 15:07    [7409055]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

Ведь здесь не надо "плясать" от справочников, разберите код на составляющие, а к нему привяжите справочники без всяких циклов - это будет достаточно быстро.


Я вот про эту фразу :)
Смотрим в примерных данных Ваших
автор
ТВК 40817...01 за гор в. 123445 1000.50 ............ 2

ТВК 40817...01 за гор в. 666111 1000.50 ............ 1
Жирным выделены повторы. Разве не требуется (при нормальном проектировании, ессьно) вынести это добро в справочник?

Позовите на помощь человека, разбирающегося в проектировании и НФ в частности.


Друг мой... Вы похоже читать-то начали все с середины...

ТВК - название классификатора (оно же и название компании). 40817...01 - название обьекта (оно же и номер счета клиента) и уже из свойств обьекта я беру остальную информацию...

Смотрите как интересно получается... Классификатор = справочник. Читайте внимательнее :)

итак архитектура

справочники
|
----------------------------
| |
справочник ком.Служб др.справочники
|
----------------------------------------------------------------
| | |
{справ} Тепловодоканал {справ.} ГорЭлектросеть {справ.} Атомная энергия на дому
|
-------------------------------
| |
{обьект} 40817...01 {обьект} 40817...02 ............тут та же ботва



есть таблица в бд на сервере: tOBjClsRelation

в ней хранится ссылка на tOBjClassifier, т.е. таблицу классификаторов или по вашему справочников, айдишник обьекта, имя обьекта, и поле Varchar, которое я назвал по своей ошибке memo (ошибка в том, что запутал Вас, мой друг)
13 июл 09, 15:20    [7409166]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
                                        справочники
                                                |
                             ----------------------------
                             |                                     |
                   справочник ком.Служб             др.справочники
                                 |
        ----------------------------------------------------------------
        |                                   |                                          |                        
{справ} Тепловодоканал  {справ.}  ГорЭлектросеть         {справ.} Атомная энергия на дому
              |                   
-------------------------------
|                                         |
{обьект} 40817...01       {обьект} 40817...02              ............тут та же ботва

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

Откуда: Москва
Сообщений: 215
Задача в том, чтобы моим отчетом перебрать ВСЕ ком.Службы и списать ВСЕ платежи со ВСЕХ счетов по ВСЕМ адресам.

Я построил свою логику по низходящей... Т.е.:
Беру компании и по каждой из них ->
Беру счет и по каждому из них ->
Беру строки в зависимости от char(13) и с каждой из них ->
Заношу эл-ты строки в поля (их 4-ре, Вино прав) в зависимости от ";" (т.е. charindex+substring)
13 июл 09, 15:27    [7409203]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal
Задача в том, чтобы моим отчетом перебрать ВСЕ ком.Службы и списать ВСЕ платежи со ВСЕХ счетов по ВСЕМ адресам.

Я построил свою логику по низходящей... Т.е.:
Беру компании и по каждой из них ->
Беру счет и по каждому из них ->
Беру строки в зависимости от char(13) и с каждой из них ->
Заношу эл-ты строки в поля (их 4-ре, Вино прав) в зависимости от ";" (т.е. charindex+substring)
Не пойму, зачем здесь такой явный процедурный подход с циклами??? Я так понимаю, входные данные - это практически и есть набор проводок на счета компаний. Ну так сделайте этот набор, например, во временную таблицу, чтобы сервер мог с ней работать стандартным способом, проиндексируйте по компаниям. А потом по нему всего по одному запросу на каждую компанию (раз уж это разные справочники), эти циклы вовсе не будут сильно затратными.
А вы самую затратную операцию - парсинг текста - оставили на куче "листьев" ???

Думаю, при вводе данных достаточно собирать эти проводки в таблицу-накопитель. А по справочникам раскидывать в подходящие моменты (например, в серъезных бухгалтерских системах с огромным объемом данных это раз в сутки, в конце дня или ночью, или перед получением баланса делается)
13 июл 09, 15:56    [7409416]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
в монопольном режиме
13 июл 09, 15:58    [7409432]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Azvaal
Друг мой... Вы похоже читать-то начали все с середины...
Даже позже. :) Друг мой - Вы слишком многослословны.

Краткость - сестра таланта (С)
13 июл 09, 16:38    [7409724]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

Да уж.. Я совсем разочаровался в себе, как в преподавателе (от слова давать, т.е. давать информацию)

Задача: приходит в банк платежка с какого-либо предприятия. В ней зарплата сотрудникам. У тех сотрудников, что написали заявление на списание с каждой зарплаты n-й суммы на оплату ком.услуг, нужно провести это самое списание.

Я решил реализовать это через отчет и классификаторы, т.е.:

В классификатор забиваем рубрики (Ком.Службы), в рубрики - обьекты (счета)

В каждом счету будет забита через точку запятой нужная информация для формирования проводки (назначение, сумма, адрес и т.п.) и через перевод строки будет разбиение по адресам.

Я беру платежку, по её номеру нахожу документы (номер у док-тов и плат. одинаковые специально) (док-т - начисление з.п. на счет клиента) беру из таблиц номера счетов и суммы начисления во временную таблицу.

Далее по каждой Ком. службе (классификатор "Период. списания" -> рубрика "ТВК" например)

просматриваю счета (рубрика "ТВК" -> обьект "40817....10" например) на момент совпадения со счетами взятыми из платежки (where tempTBL.ResourceID = classRubrikaTBL.ObjectID например)

и далее уже обрабатываю каждый счет...

Выше можете найти сам код, здесь я лишь описал алгоритм...

Не пойму никак, что же мне сделать, чтобы последовать вашему совету, ув. Vino
14 июл 09, 06:17    [7411358]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

Да уж.. Я совсем разочаровался в себе, как в преподавателе (от слова давать, т.е. давать информацию)

Задача: приходит в банк платежка с какого-либо предприятия. В ней зарплата сотрудникам. У тех сотрудников, что написали заявление на списание с каждой зарплаты n-й суммы на оплату ком.услуг, нужно провести это самое списание.

Я решил реализовать это через отчет и классификаторы, т.е.:

В классификатор забиваем рубрики (Ком.Службы), в рубрики - обьекты (счета)

В каждом счету будет забита через точку запятой нужная информация для формирования проводки (назначение, сумма, адрес и т.п.) и через перевод строки будет разбиение по адресам.

Я беру платежку, по её номеру нахожу документы (номер у док-тов и плат. одинаковые специально) (док-т - начисление з.п. на счет клиента) беру из таблиц номера счетов и суммы начисления во временную таблицу.

Далее по каждой Ком. службе (классификатор "Период. списания" -> рубрика "ТВК" например)

просматриваю счета (рубрика "ТВК" -> обьект "40817....10" например) на момент совпадения со счетами взятыми из платежки (where tempTBL.ResourceID = classRubrikaTBL.ObjectID например)

и далее уже обрабатываю каждый счет...

Выше можете найти сам код, здесь я лишь описал алгоритм...

Не пойму никак, что же мне сделать, чтобы последовать вашему совету, ув. Vino



Вся система работает на MS SQL 2000, т.е. классификатор - строка в таблице с полем ChildID, которое указывает на айдишник рубрики классификатора в этой же таблице. Обьекты хранятся в другой таблице, в которой есть свое поле, для привязки обьектов к рубрикам (айдишник т.е. )))
14 июл 09, 06:22    [7411364]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

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

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

Для этого мне требуется переписать код. Отчет итак вешал сервак, на котором работаю СОВСЕМ не я один.. Теперь же, если я добавлю ещё один курсор + Цикл он вообще нафиГ рухнет к чертям. Не особо этого хочется )))

Кстати, насчет "не мешать пользователям" - сделайте все запросы без блокировок, так как этот отчет не в реальном времени
А насчет скрипта - непросто понять, что он делает, так как ни примера исходных данных, ни комментариев нет
14 июл 09, 11:52    [7412461]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

щас пытался написать комменты.. Анриал, офк :))
14 июл 09, 12:33    [7412737]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal, и все же рекомендую насчет "не мешать пользователям" - сделайте все запросы без блокировок, попробуйте хотя бы проставить в самых грузовых селектах хинты with(nolock)
14 июл 09, 14:42    [7413666]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

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

Да, обязательно... Теперь вот такой трабл...

create table #END
(Summ money
,Prim3 varchar(255)
,LicSchet varchar(10)
,Prim5 varchar(10))

declare @Str varchar(255)
,@Start int
,@End int
,@Summ varchar(50)
,@Prim3 varchar(50)
,@LicSchet varchar(50)
,@Prim5 varchar(50)
,@S varchar(50)

select @Str = 
'1000;12345;коммент;адрес
300;12345;коммент;адрес2
300;12345;коммент;адрес2'

select @End   = charindex(char(13),@Str)

while @End > 0
begin
  select @S  = substring(@Str,1,@End-1)
  set @Str   = substring(@Str,@End+2,len(@Str))
  set @End   = charindex(char(13),@Str)
 
select @S
end

drop table #END

разбивает на строки. Далее таким же макаром разбиваю внутри на слова.
Но, во-первых, теряется последняя строка/слово.
Во-вторых, внутри двух курсоров.. Это ппц... Подскажите..?
14 июл 09, 14:53    [7413740]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal
vino,

Да, обязательно... Теперь вот такой трабл...

create table #END
(Summ money
,Prim3 varchar(255)
,LicSchet varchar(10)
,Prim5 varchar(10))

declare @Str varchar(255)
,@Start int
,@End int
,@Summ varchar(50)
,@Prim3 varchar(50)
,@LicSchet varchar(50)
,@Prim5 varchar(50)
,@S varchar(50)

select @Str = 
'1000;12345;коммент;адрес
300;12345;коммент;адрес2
300;12345;коммент;адрес2'

select @End   = charindex(char(13),@Str)

while @End > 0
begin
  select @S  = substring(@Str,1,@End-1)
  set @Str   = substring(@Str,@End+2,len(@Str))
  set @End   = charindex(char(13),@Str)
 
select @S
end

drop table #END

разбивает на строки. Далее таким же макаром разбиваю внутри на слова.
Но, во-первых, теряется последняя строка/слово.
Во-вторых, внутри двух курсоров.. Это ппц... Подскажите..?

Обычно для рекурсивных алгоритмов в исходные данные добавляют недостающие данные, в данном случае
select @Str = 
'1000;12345;коммент;адрес
300;12345;коммент;адрес2
300;12345;коммент;адрес2'+char(13)
14 июл 09, 15:03    [7413841]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
для итеративных алгоритмов
14 июл 09, 15:06    [7413853]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
дык пойми, что юзеры не всегда добавят энтер или последнюю точку с запятой в поле
14 июл 09, 15:13    [7413919]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Azvaal, а я и не говорил про пользователей
14 июл 09, 15:17    [7413947]     Ответить | Цитировать Сообщить модератору
 Re: Разобрать строку  [new]
vino
Member

Откуда:
Сообщений: 1191
Конечно, есть вариант кода добавить для учета недостающего последнего окончания строки, но это изврат
...
declare @Str      varchar(255)
       ,@Start    int
       ,@End      int
       ,@Summ     varchar(50)
       ,@Prim3    varchar(50)
       ,@LicSchet varchar(50)
       ,@Prim5    varchar(50)
       ,@S        varchar(50)

select @Str = 
'1000;12345;коммент;адрес
300;12345;коммент;адрес2
300;12345;коммент;адрес2'

select @End   = charindex(char(13),@Str)

while @End > 0
begin
set @End   = charindex(char(13),@Str)
set @End   = CASE WHEN @End > 0 THEN @End ELSE len(@Str) END

while @End > 0
begin
	select @S  = substring(@Str,1,@End-1)
	set @Str   = substring(@Str,@End+2,len(@Str))
	set @End   = charindex(char(13),@Str)
	set @End   = CASE WHEN @End > 0 THEN @End ELSE len(@Str) END
select @S
end
...
14 июл 09, 15:23    [7414000]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить