powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Пакетное выполнение команд, сравнение - строк 2 вопроса
6 сообщений из 31, страница 2 из 2
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33407419
Игорь2004
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To gardenman
“я как раз и имел в виду рекурсивные запрос”
У меня была смутная догадка на этот счет, я искал по слову «virtual» но ничего не нашел.

“Кстати, в том же COOK BOOK есть пример Normalize/Denormalize data. Это как раз вам в тему.”
Да, именно так.

« И, если мне не изменяет память здесь на форуме был уже пример как строку разложить по словам в таблицу.»
Мне ничего найти не удалось.

«даже не смотря на то, что SQL позволяет все это сделать решил бы ее на C/C++. Я конечно затрачу времени на это раза в 2-3 больше, но производительность увеличится раз в 100. Причем табличные функции на C/C++ именно в DB2 пишутся просто влет.»
А с каким компилятором пишуться программы на C/C++ для DB2 ?
А интересно было бы сравнить разницу в скорости ?
Есть ли бесплатные компиляторы для этой цели, и примеры того как нужно писать , компилировать и вызывать написанное из DB2 ?

«Кстати, объясните пожалуйста зачем cScting и cDelemiters вы делаете FOR BIT DATA.»
1) Скорость работы строковых функций по моему предположению должна быть выше поскольку не зависит от Collattion Setting
2) Сравнение и поиск всегда чувствительны к регистру (вдруг все таки есть базы нечувствительные к регистру)
Все это мои предположения, хотя вроде что –то мельком видел в документации.



To Виктор
«Каким же образом? Строки ведь заблокированы до завершения транзакции. Вот добавить своё (в новой DB2; в старой тоже сядет на блокировку), пожалуй, сможет.» Я предполагал нечто подобно, и хотел получить подтверждение.

«пока лень вникать в ваш алгоритм.» Алгоритм надежный как автомат Калашникова, просто в DB2 выглядит некрасиво.

« В чём вы видите "не является простым"? В том, что разделители могут быть разными? Так их можно свести к одному (пробелу) при помощи функции TRANSLATE»
Читая пример я тоже до этого додумался. Но сводить в общем случае не к пробелу (ведь его может и не быть в строке из символов разделителей),
а к одному из (любому) символов из строки разделителей, в частном случае лучше к пробелу.

«там была небольшая ошибка, но её легко исправить».
На самом деле две ошибки – пример не работал при пустом символе разделителе, и в двух местах нужно было вычесть 1.

Ну что ж в итоге получилась функция (будет время сравню по скорости с предыдущим вариантом) ,
Работает и пустым разделителем, и с единым разделителем состоящим из нескольких разных символов.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
-- вспомогательная функция ( в общем случае мне нужно обрезать  единый разделитель состоящий из нескольких разных символов,
-- пробел является часным случаем
CREATE FUNCTION VFP.MYLTRIM
(cExpressionSearched VARCHAR( 4000 ), cSearchExpression VARCHAR( 256 ))
RETURNS VARCHAR( 4000 )
SPECIFIC  MYLTRIM
DETERMINISTIC NO EXTERNAL ACTION CONTAINS SQL
BEGIN ATOMIC
    DECLARE   i, len, lencSearchExpression  SMALLINT;
    DECLARE cLtrimString VARCHAR( 4000 );
    SET  i  =   1 ,  len  =  LENGTH(cExpressionSearched),  lencSearchExpression  =  LENGTH(cSearchExpression) ;
    IF  lencSearchExpression =  1  and ASCII(cSearchExpression) =  32  THEN
       SET cLtrimString  = LTRIM(cExpressionSearched);
    ELSE
     IF  lencSearchExpression >  0  THEN
         IF  len >  0  THEN
      	    BOUCLE: WHILE i <= len   DO
     	      IF  (i + lencSearchExpression -  1 ) > len OR LOCATE(cSearchExpression, SUBSTR(cExpressionSearched, i, lencSearchExpression)) =  0  THEN
	            LEAVE  BOUCLE;
      	      END IF;
              SET   i =   i  +  lencSearchExpression;
            END WHILE;
           SET cLtrimString = RIGHT(cExpressionSearched, len - i +  1 ) ;
         ELSE
          SET cLtrimString = '';
        END IF;
      ELSE
        SET cLtrimString = cExpressionSearched;
      END IF;
   END IF;
  RETURN cLtrimString;
END



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
CREATE FUNCTION VFP.GETALLWORDS2
(cString1 VARCHAR( 4000 ), cStringSplitting1 VARCHAR( 256 ))
RETURNS table (WORDNUM SMALLINT, WORD VARCHAR( 4000 ), STARTOFWORD SMALLINT, LENGTHOFWORD SMALLINT)
SPECIFIC GETALLWORDS2
DETERMINISTIC NO EXTERNAL ACTION CONTAINS SQL
-- GETALLWORDS2() User-Defined Function Inserts the words from a string into the table.
 -- GETALLWORDS2( cString[,  cStringSplitting])
 -- Parameters
 -- cString   varchar(4000) - Specifies the string whose words will be inserted into the table  GETALLWORDS2.
 -- cStringSplitting  varchar(256) - Optional. Specifies the string used to separate words in  cString.
 -- The default delimiter is space.
 -- Note that GETALLWORDS2( ) uses   cStringSplitting as a single delimiter.
 -- Return Value table
 -- Remarks GETALLWORDS2() by default assumes that words are delimited by space. If you specify another string as delimiter, this function ignores spaces and uses only the specified string.
 -- Example
 -- SELECT WORD FROM TABLE(VFP.GETALLWORDS2('We hold these truths to be self-evident,
 that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty
 and the pursuit of Happiness.')) AS A where WORDNUM = 30 ;  -- Displays 'Liberty'
 -- SELECT WORDNUM  FROM TABLE(VFP.GETALLWORDS2('SQL Procedural Language DB2')) AS A ORDER BY WORDNUM DESC FETCH FIRST 1 ROW ONLY; -- Displays 4
 -- See Also GETWORDNUM() , GETWORDCOUNT() ,  GETALLWORDS()  User-Defined Functions
BEGIN ATOMIC
    DECLARE nEndString, nLenSrtingSplitting, BegOfWord SMALLINT;
    DECLARE cString  VARCHAR( 4000 );
    DECLARE cStringSplitting VARCHAR( 256 );
    SET  cString = cString1,  cStringSplitting = cStringSplitting1, BegOfWord =  1  ;
    SET  cString  =  COALESCE(cString, ''), cStringSplitting  =  COALESCE(cStringSplitting, ' '), nLenSrtingSplitting  =  LENGTH(cStringSplitting), nEndString  =  1  + LENGTH(cString);

    IF nLenSrtingSplitting >  0   THEN
               WHILE BegOfWord < (nEndString - nLenSrtingSplitting +  1  )  AND  LOCATE(SUBSTR(cString, BegOfWord, nLenSrtingSplitting), cStringSplitting) >  0      DO
                     SET   BegOfWord =   BegOfWord  +  nLenSrtingSplitting; --  skip break strings, if any
               END WHILE;
               SET  cString = SUBSTR(cString, BegOfWord);
    END IF;
RETURN WITH
   TEMP1 ( STRING) AS (VALUES (cString) ),
   TEMP2 ( WORDNUM, STARTOFWORD, WORD, STRING_LEFT) AS
   (SELECT  SMALLINT( 1 ), BegOfWord,
   SUBSTR(STRING, 1 , CASE WHEN LOCATE(cStringSplitting, STRING) =  0  OR nLenSrtingSplitting =  0  THEN LENGTH(STRING) ELSE LOCATE(cStringSplitting,STRING) -  1  END),
   CASE WHEN nLenSrtingSplitting =  0  THEN '' ELSE VFP.MYLTRIM(SUBSTR(STRING, CASE LOCATE(cStringSplitting, STRING) WHEN   0  THEN LENGTH(STRING) + nLenSrtingSplitting ELSE LOCATE(cStringSplitting,STRING) END), cStringSplitting)  END
   FROM TEMP1 WHERE STRING <> ''
   UNION ALL
     SELECT WORDNUM +  1 ,  nEndString - length(STRING_LEFT),
     SUBSTR(STRING_LEFT, 1 , CASE LOCATE(cStringSplitting,STRING_LEFT) WHEN  0  THEN LENGTH(STRING_LEFT) ELSE LOCATE(cStringSplitting,STRING_LEFT) -  1  END),
     VFP.MYLTRIM(SUBSTR(STRING_LEFT, CASE LOCATE(cStringSplitting,STRING_LEFT) WHEN  0  THEN LENGTH(STRING_LEFT) + nLenSrtingSplitting ELSE LOCATE(cStringSplitting,STRING_LEFT) END), cStringSplitting)
     FROM TEMP2 WHERE STRING_LEFT <> '' )
  SELECT WORDNUM, WORD, STARTOFWORD, LENGTH(WORD) FROM TEMP2 ORDER BY  1 ;
END


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE FUNCTION VFP.GETALLWORDS
(cString1 VARCHAR( 4000 ), cDelimiters VARCHAR( 256 ))
RETURNS table (WORDNUM SMALLINT, WORD VARCHAR( 4000 ), STARTOFWORD SMALLINT, LENGTHOFWORD SMALLINT)
SPECIFIC  GETALLWORDS
DETERMINISTIC NO EXTERNAL ACTION MODIFIES SQL DATA
-- GETALLWORDS() User-Defined Function Inserts the words from a string into the table.
 -- GETALLWORDS( cString[,  cDelimiters])
 -- Parameters
 -- cString   varchar(4000) - Specifies the string whose words will be inserted into the table  GETALLWORDS. 
 -- cDelimiters  varchar(256) - Optional. Specifies one or more optional characters used to separate words in  cString.
 -- The default delimiters are space, tab, carriage return, and line feed. Note that GETALLWORDS( ) uses each of the characters in  cDelimiters as individual delimiters, not the entire string as a single delimiter. 
 -- Return Value table 
 -- Remarks GETALLWORDS() by default assumes that words are delimited by spaces or tabs. If you specify another character as delimiter, this function ignores spaces and tabs and uses only the specified character.
 -- Example
 -- SELECT *  FROM TABLE(VFP.GETALLWORDS('The default delimiters are space, tab, carriage return, and line feed.
 If you specify another character as delimiter, this function ignores spaces and tabs and uses only the specified character.')) AS A;
 -- See Also GETWORDNUM() , GETWORDCOUNT() User-Defined Functions 
BEGIN ATOMIC
     DECLARE cCharSplitting VARCHAR( 1 ) DEFAULT '';
     DECLARE cString  VARCHAR( 4000 );
     SET  cString = cString1;
     IF  LENGTH(cDelimiters) >  0   THEN
        IF LOCATE(SPACE( 1 ), cDelimiters) >  0  THEN
            SET cCharSplitting = SPACE( 1 );
        ELSE
            SET cCharSplitting = LEFT(cDelimiters, 1 ) ;
        END IF;
        SET cString = TRANSLATE(cString, REPEAT(cCharSplitting,  LENGTH(cDelimiters)), cDelimiters);
     END IF;

   RETURN SELECT WORDNUM, WORD, STARTOFWORD, LENGTHOFWORD  FROM TABLE(VFP.GETALLWORDS2(cString, CAST(cCharSplitting AS VARCHAR( 256 )))) AS GETALLWORDS;
END

Еще раз спасибо за высказанные мнения и полезные советы.
...
Рейтинг: 0 / 0
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33407905
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> А с каким компилятором пишуться программы на C/C++ для DB2 ?
> А интересно было бы сравнить разницу в скорости ?

Если вы на виндовой платформе это делаете, то можете скачать MinGW (www.mingw.org) - это будет абсолютно бесплатно (gcc ).
Или можете воспользоваться MS Visual С++ (любая версия)
Ежели вы под Linux хотите - то там всегда gcc есть.Под AIX наверно icc или опять же gcc. Как и под Solaris.

Кстати, был такой пример, когда я генерил строку случайных символов таким образом: CHR(INT(RAND()*25+65))||CHR(INT(RAND()*25+65))||CHR(INT(RAND()*25+65))||...
А потом реализовал то же самое, но на C++...
Разница в производительности была на порядок. Причем естественно зависила от длины строки.

Если вам действительно не лень, и действительно хочется добиться крутой производительности, то реализуйте эту функцию на C++. В принципе могу даже помочь)))
...
Рейтинг: 0 / 0
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33410107
Игорь2004
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To gardenman
Спасибо.
Если бы я решил переписать свои функции на C, то у меня основное время ушло бы на поиск примеров таких функций для DB2, с какими опциями компилировать, как вызывать из DB2 - поскольку у меня нет такого опыта.
Что касается конвертации строки символов в таблицу, то ведь все равно придется задействовать вызов SQL DB2 только уже из функции написанной на C и там, вероятно, разница в скорости не будет столь значительной.
Что касается работы со строками, то разница в скорости конечно будет большой.
...
Рейтинг: 0 / 0
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33410283
Herr Developer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Интересно, если тоже самое и сделать на Java или .NET языке (Windows only), насколько бы это было бы конкурентноспособным по сравнению с C/C++...
...
Рейтинг: 0 / 0
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33410890
ggv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ggv
Гость
Игорь - в дистре db2 идет просто куча примеров на все случаИ жизнИ.

ACRUS - только вчера общался с разработчиками приложений DB2 (и эти приложения используете и вы - только не знаете), которые пишут на ASM.
В отношении SP у них такое же мнение, как и у gardenman и у меня. С поправкой - если надо, то уж лучше на С
...
Рейтинг: 0 / 0
Пакетное выполнение команд, сравнение - строк 2 вопроса
    #33411107
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Что касается конвертации строки символов в таблицу, то ведь все равно придется задействовать вызов SQL DB2

Основные ресурсы при работе виртуальной машины SQL - это распредение/освобожнение памяти особенно когда работаете с такими типами как VARCHAR/LOB. У DB2 при написании внешних функций есть отличная штука - SCRATCHPAD (поищите тут по форуму). Этим можно очень эффективно пользоваться. Поэтому когда я говорю что производительность можно увеличить на порядок - это правда.
...
Рейтинг: 0 / 0
6 сообщений из 31, страница 2 из 2
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Пакетное выполнение команд, сравнение - строк 2 вопроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]