Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
1) Если я правильно понял, в окне Редактора команд нельзя выполнять команды типа IF, CREATE FUNCTION Каким наиболее оптимальным образом (в каком окне, что нужно сделать для вызова этого окна) можно выполнить команды вида IF EXISTS (SELECT * FROM SYSCAT.ROUTINES WHERE ROUTINESCHEMA = 'VFP' AND ROUTINENAME = 'AT' ) THEN DROP FUNCTION VFP.AT ; END IF ; IF EXISTS (SELECT * FROM SYSCAT.ROUTINES WHERE ROUTINESCHEMA = 'VFP' AND ROUTINENAME = 'RAT' ) THEN DROP FUNCTION VFP.RAT ; END IF ; то есть я проверяю наличие пользовательских функций и затем их удаляю и затем создание нескольких пользовательских функций ? то есть выполнение несколько команд вида CREATE FUNCTION Если я правильно понял, то аналогом команды GO MS SQL Server является команда @ ? 2) Точное (бинарное) сравнение и поиск в строках Есть ли возможность при создании базы данных задать, какое будет сравнение строк - чувствительное к регистру case-sensitive или нечувствительное к регистру case-insensitive, то есть функции для работы со строками (типа locate, translate, replace) будут работать по разному в зависимости от установки ? Если я правильно понял документацию, то такой возможности в явном виде нет, и сравнение зависит от collating sequence ? В документации я нашел несколько примеров collating sequence SQL_CS_SYSTEM, SQL_CS_SYSTEM_NLSCHA, SQL_CS_IDENTITY_16BIT и т.д. Во всех присутствует CS - case-sensitive , отсюда вопрос встречал ли кто-нибудь в своей практике collating sequence в которой сравнение и поиск строк был бы нечувствительным к регистру ? Не имеет ли смысл использовать тип FOR BIT DATA для гарантированного бинарного сравнения и поиска в строках независимо от collating sequence ? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2005, 19:07 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Речь идет о базе данных DB2 Express. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2005, 19:09 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Конечно, в "Редакторе команд" можно выполнять как IF...THEN, так и CREATE FUNCTION. Вот с сочетанием различных команд могут возникнуть проблемы. Перво-наперво, чтобы успешно выполнять команды типа CREATE FUNCTION, надо понимать смысл завершителей (statement termination character). Рассмотрим Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2005, 23:30 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Пункт второй - EXISTS. В DB2 из IF его, к сожалению, не вызвать. Надо писать что-то вроде Код: plaintext 1. 2. 3. 4. 5. 6. Как я помню, в BEGIN ATOMIC ... END такие манипуляции невозможны, а BEGIN ... END должно быть частью хранимой процедуры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2005, 23:34 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Зачем такие сложности (раньше был аналогичный вопрос с DROP'анием таблицы), когда можно просто писать, не утруждая себя проверками, Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2005, 23:37 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
@ - это не аналог MS SQL go, а просто разделитель. Можно выбрать другой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2005, 23:38 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Сравнение строк в DB2 чувствительно к регистру. Нечувствительное придётся задавать как SELECT ... FROM ... WHERE ucase(field) = ucase(:value). Индексов по функциям на данный момент нет, но есть суррогат. Если определить поле a la u_field generated always as (ucase(field)) то оптимизер может осуществить подстановку как SELECT ... FROM ... WHERE u_field = ucase(:value) а по u_field можно создавать индекс ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2005, 23:43 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Виктор, большое спасибо за полный ответ. Еще один вопрос к Вам, как к эксперту, но сначала небольшое предисловие. Если я правильно понял, я не могу в пользовательской функции выполнять следующие команды CREATE TABLE DECLARE GLOBAL TEMPORARY TABLE Теперь предположим, я пишу пользовательскую функцию, возвращающую таблицу ( в MS SQL Server я, к примеру, могу задать в такой функции имя возвращаемой таблицы), которая слова из строки символов помещает в таблицу. В DB2 я должен обращаться к уже существующим таблицам – поэтому я не нашел лучшего решения как создать командой CREATE TABLE SESSION.МОЯ_ТАБЛИЦА фиктивную таблицу для того, чтобы собрать пользовательскую функцию без появления сообщений типа «я не могу найти таблицу SESSION.МОЯ_ТАБЛИЦА», затем перед вызовом моей пользовательской функции я выполняю команду DECLARE GLOBAL TEMPORARY TABLE МОЯ_ТАБЛИЦА И при работе пользовательской функции при обращении к SESSION.МОЯ_ТАБЛИЦА происходит обращение в временной таблице, поскольку в соответствии с документацией при одновременном существовании постоянной таблицы МОЯ_ТАБЛИЦА в схеме SESSION и одноименной временной таблице обращение к SESSION.МОЯ_ТАБЛИЦА относится к временной таблице. Является ли найденный мной вариант наилучшим, можете ли Вы предложить нечто лучшее? То есть пользовательская функция должна в идеале работать каждая со своей таблицей и возвращать в виде таблицы некий результат. Спасибо. Кстати, нашел интересное поведение функции Locate. values locate('','string',100); возвращает 100, вообще, можно указать любое число в качестве третьего аргумента и функция возвратит его (если первый аргумент пустая строка). Хотя должна была бы возвращать всегда 0. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 07:23 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
автор Теперь предположим, я пишу пользовательскую функцию, возвращающую таблицу ( в MS SQL Server я, к примеру, могу задать в такой функции имя возвращаемой таблицы), которая слова из строки символов помещает в таблицу. В DB2 я должен обращаться к уже существующим таблицам – поэтому я не нашел лучшего решения как создать командой CREATE TABLE SESSION.МОЯ_ТАБЛИЦА фиктивную таблицу Честно говоря не пойму зачем так делать? Неужели обыкновенного SQL не хватает? Можно ведь создать э... виртуальную временную таблицу, которая целиком раполагается в памяти. И работать будет быстрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 11:12 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
наверное, наследие ms sql почему-то работающие с ним очень _активно_ используют временные таблицы, но это субъективное наблюдение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 14:46 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
ggvнаверное, наследие ms sql почему-то работающие с ним очень _активно_ используют временные таблицы, но это субъективное наблюдение Это не субъективное наблюдение. Такая же фигня с теми кто юзает Sybase. У этих баз (они же родственники) SQL очень слаб. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 16:05 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
недавно давал "рецензию" по поводу возможности миграции проекта с ms sql на db2. Посмотрел DDL скрипты, с просто неописуемым количеством temp tables, по нескольку штук в SP, поговорил с разработчиками - к ms sql претензий нет, все устраивает, вот только временные таблицы, вот с ними бы получше, чтоб не клинило так когда их много...... no comments ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 16:58 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
2 Игорь2004: Я DECLARE GLOBAL TEMPORARY TABLE ещё не разу не использовал - просто не было нужды. Почитайте лучше "кулинарную книжку" с http://ourworld.compuserve.com/homepages/Graeme_Birchall/HTM_COOK.HTM Если вы всё-таки будете настаивать на временных таблицах, то... поищите http://groups.google.com/group/comp.databases.ibm-db2, да на news://news.software.ibm.com, там были обсуждения. Я читал, но забыл почти сразу, о чём там говорилось. Помню только, что там есть свои тонкости, и вообще не факт, что к временной таблице можно обратиться из UDF (). Скорее нет, чем да. Важный момент. "при одновременном существовании постоянной таблицы МОЯ_ТАБЛИЦА в схеме SESSION и одноименной временной таблице обращение к SESSION.МОЯ_ТАБЛИЦА относится к временной таблице." Очевидно, это относится к компиляции SQL-выражения. Предположим, на момент T1 временная таблица ещё не определена, вы скомпилировали SQL-выражение в момент T2, и затем определили временную таблицу в момент T3. В T4 выполнили SQL, но план SQL-выражения уже определён. Как я понимаю, план не должен измениться. А хранимая процедура на SQL в DB2, как правило, использует Static SQL, т.е. план хранится в базе. Стало быть, см ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 18:44 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
URL не туда попал - он про temporary в UDF. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 18:45 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
UDF - не Static SQL, а фактически макроподстановка, компилируется вместе с вызвавшим её SQL-выражением, так что шансы могут быть. Но план надо смотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 18:47 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
да и здесь на форуме что-то было --- типа, невыполнимое условие в теле процедуры, под условием - DECLARE GLOBAL TEMPORARY TABLE и компилятор не ругается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 18:49 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
(я успел немного погуглить) в ньюсгруппе comp.databases.ibm-db2 Серж Релю (?) предлагал решение Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 20:47 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Victor Metelitsa Важный момент. "при одновременном существовании постоянной таблицы МОЯ_ТАБЛИЦА в схеме SESSION и одноименной временной таблице обращение к SESSION.МОЯ_ТАБЛИЦА относится к временной таблице." Очевидно, это относится к компиляции SQL-выражения. Предположим, на момент T1 временная таблица ещё не определена, вы скомпилировали SQL-выражение в момент T2, и затем определили временную таблицу в момент T3. В T4 выполнили SQL, но план SQL-выражения уже определён. Как я понимаю, план не должен измениться. А хранимая процедура на SQL в DB2, как правило, использует Static SQL, т.е. план хранится в базе. Неверно. When binding a package that has static SQL statements that refer to tables implicitly or explicitly qualified by SESSION, those statements will not be bound statically. When these statements are invoked, they will be incrementally bound, regardless of the VALIDATE option chosen while binding the package. At runtime, each table reference will be resolved to a declared temporary table, if it exists, or a permanent table. If neither exists, an error will be raised (SQLSTATE 42704). Но это к SP и т.п., а насчёт UDF всё ещё непонятно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 21:11 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
А вот теперь всё ясно. Restrictions on the Use of Declared Global Temporary Tables: Declared global temporary tables cannot: – Be specified in an ALTER, COMMENT, GRANT, LOCK, RENAME or REVOKE statement (SQLSTATE 42995). – Be referenced in a CREATE ALIAS, CREATE FUNCTION (SQL Scalar, Table, or Row), CREATE TRIGGER, or CREATE VIEW statement (SQLSTATE 42995). – Be specified in referential constraints (SQLSTATE 42995). Очевидно, я это всё читал, но забыл. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 21:14 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Вывод: читайте кулинарную книжку. http://ourworld.compuserve.com/homepages/Graeme_Birchall/HTM_COOK.HTM ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2005, 21:15 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
gardenman ggvнаверное, наследие ms sql почему-то работающие с ним очень _активно_ используют временные таблицы, но это субъективное наблюдение Это не субъективное наблюдение. Такая же фигня с теми кто юзает Sybase. У этих баз (они же родственники) SQL очень слаб. Слабый SQL это не главная причина. Я например тоже спокойно юзаю локальные и глобальные времянки на WatcomSQL, хотя его слабым назвать по отношению MSSQL/Sybase ASE нельзя. Глобальные времянки позволяют клиентскому приложению сессионно хранить промежуточные данные (например юзер понащелкал в списке, что должно попасть в отчет, клиентская прога это сохранила в глобальную времянку и вызвала отчет, который обычным джойном по заполненной времянке уже фильтрует в отчет только то, что нужно). Локальные времянки же используются внутри ХП для разруливания сложных запросов, промежуточных аггрегаций, используемых многократно и борьбы с блокировками. С учетом того, что у нас глобальные и локальные времянки можно обьявлять как NOT TRANSACTIONAL и нет такого тяжелого наследия, как TempDB у MSSQL, то с времянками все просто летает. И кстати на глобальные времянки можно вешать все что угодно и использовать где угодно, кроме FOREIGN KEY. Хоть триггеры писать - что иногда очень даже неплохо. Так что не надо удивляться тому, чего не понимаешь - я вот например в тихом шоке, что DB2-шники хранимки предпочитают на C писать и вообще тут язык хранимых процедур насколько я понимаю не очень то давно появился, я не представляю, как без него в СУБД можно было обходится - судя по работающим проектам на DB2 - можно, хотя мне понять и сложно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 07:05 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Спасибо всем участникам за высказанные мнения. TO gardenman “Можно ведь создать э... виртуальную временную таблицу, которая целиком раполагается в памяти” А каким образом можно создать виртуальную временную таблицу ? Я ничего про виртуальные временные таблицы, к сожалению, не нашел в документации. Только про временные и глобальные временные таблицы. To Виктор Вы совершенно правы касательно временных таблиц (из функции их просто не видно). Спасибо за порекомендованую книжку, весьма доступно и хорошо написана. Мне там понравился следующий пример, в котором таблица наполняется «из воздуха», если можно так выразится. Вот этот пример Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. не обращаться ни к какой постоянной таблице. Вот описание моей функции GETALLWORDS() Функция определенная пользователем Помещает в таблицу все слова из строки GETALLWORDS( cString[, cDelimiters]) Тип возвращаемого значения таблица GETALLWORDS (WORDNUM smallint, WORD varchar(4000), STARTOFWORD smallint, LENGTHOFWORD smallint) Описание структуры возвращаемой таблицы GETALLWORDS поле WORDNUM smallint – порядковый номер слова в строке cString поле WORD varchar(4000) - слово поле STARTOFWORD smallint – позиция в строке cString, с которой начинается слово поле LENGTHOFWORD smallint – длина слова Параметры cString varchar(4000) – строка, слова которой будут помещены в таблицу GETALLWORDS. cDelimiters varchar(256) - необязательный параметр, определяет те символы, которые будут служить разделителями слов в строке cString. Разделителями по умолчанию являются пробелы, символы табуляции, возврата каретки и перевода строки. GETALLWORDS() считает каждый символ из строки cDelimiters как отдельный разделитель, а не всю строку cDelimiters как единый разделитель. Примечания: GETALLWORDS() по умолчанию считает, что слова разделены пробелами, символами табуляции, возврата каретки и перевода строки. Если передан параметр cDelimiters, функция игнорирует пробелы, символы табуляции, возврата каретки и перевода строки. Пример вызова: Код: plaintext 1. 2. при последующих вызовах удалять записи, вставленные в предыдущих вызовах. Но у моего решения возможно есть недостаток – теоретически при большом количестве вызовов, один пользователь Может удалить записи вставленные другим пользователем. Это место показано в коде. Не говяря уже о том что наверняка есть более красивое решение. Отсюда вопрос – может ли кто-нибудь предложить другое, более элегантное решение. Использовать временную таблицу (наполняя ее в самой функции как в приведенном выше прмере из «кулинарной» книги мне не удалось, поскольку, алгоритм поиска слов в строке не является простым). Вот код моей функции Код: 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. При всех недостатках MS SQL Server там данная задача решалась легко, возможно и DB2 есть нормальное решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 07:48 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
2 Игорь "виртуальную временную таблицу" я как раз и имел в виду рекурсивные запросы. Вы наверное никогда не пробовали юзать рекурсивный SQL. Попробуйте. Кстати, в том же COOK BOOK есть пример Normalize/Denormalize data. Это как раз вам в тему. И, если мне не изменяет память здесь на форуме был уже пример как строку разложить по словам в таблицу. И, еще, если вдруг вам придет в голову создать выражение, которое возвращает конкретное число записей, посмотрите в сторону values: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. А что касается использовать SQL для решения задач подобной вашей, я .. даже не смотря на то, что SQL позволяет все это сделать решил бы ее на C/C++. Я конечно затрачу времени на это раза в 2-3 больше, но производительность увеличится раз в 100. Причем табличные функции на C/C++ именно в DB2 пишутся просто влет. Задача приведенная вами - сугубо вычислительная. Жрет много процессорных ресурсов. Кстати, объясните пожалуйста зачем cScting и cDelemiters вы делаете FOR BIT DATA. 2 ASCRUS У DB2 есть спицифика в разработке. Особые фичи.Особый путь. Которым можно и не пользоваться. Я здесь на форуме неоднократно говорил о том, что такое Static SQL. Для чего нужны ХП? Для того, чтобы избавится от затрат времени на компиляцию. Для того, чтобы перенести бизнес-логику на сервер. А в DB2 это возможно и без ХП. С помощью статического SQL. Причем производительность только выростет. Если действительно есть желание с этим разобраться почитайте про команды BIND и PREP и про статический SQL. Что касается временных таблиц в DB2. Когда вы создаете временную таблицу инфа о ней не хранится в системном каталоге. Я даже не знаю способа посмотреть список всех временных таблиц. Да и получить структуру временной таблицы можно лишь так: describe select * from <tmpеtable> Поэтому при создании времянок нет никаких блокировок в системном каталоге. но с другой стороны и триггеров не создать Короче все приносится в жертву только одному - производительности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 11:03 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Извините, пока лень вникать в ваш алгоритм. В чём вы видите "не является простым"? В том, что разделители могут быть разными? Так их можно свести к одному (пробелу) при помощи функции TRANSLATE, после чего уже воспользоваться примером из кулинарной книжки, разбирающим строку на слова (там была небольшая ошибка, но её легко исправить). При этом нумерация получается легко, а длина слова получается, естественно, функцией LENGTH от этого слова. (lenght(WORD)=LENGTHOFWORD) Над вычислением STARTOFWORD надо подумать. Скажем, можно попробовать так: рекурсивный алгоритм "поедает" анализируемую строку, и зная начальную длину и длину "поедаемого" остатка, можно определить и STARTOFWORD. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 17:52 |
|
||
|
Пакетное выполнение команд, сравнение - строк 2 вопроса
|
|||
|---|---|---|---|
|
#18+
Игорь2004 -- вот узкое место (на мой взгляд) в данный момент кто-нибудь может удалить -- только что полученный реультат Каким же образом? Строки ведь заблокированы до завершения транзакции. Вот добавить своё (в новой DB2; в старой тоже сядет на блокировку), пожалуй, сможет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 17:55 |
|
||
|
|

start [/forum/topic.php?fid=43&msg=33388434&tid=1605653]: |
0ms |
get settings: |
7ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
131ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
78ms |
get tp. blocked users: |
1ms |
| others: | 259ms |
| total: | 510ms |

| 0 / 0 |
