Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> регулярные выражения в MSSQL T-SQL 
V
    Опции темы
skyboy
Дата 4.12.2007, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 2
Всего: 260



Понадобились мне регулярные выражения. После оператора REGEXP в mysql, ожидал нечто подобное и в таком монстре, как MSSQL Server. А оказалось - нету такого. В поисках downloadable UDF-библиотеки наткнулся на статью на sqlteam.com, где описано создание функции для работы с регулярными выражениями при помощи использования объекта VBScript.Regexp. Ну, да, я забыл, что T-SQL может ссылаться не только на библиотеки dll, но и на ActiveX-объекты. Все же, кроссплатформенность даже не предполагается.
Таким образом, функция выглядить следующим образом:
Код

CREATE FUNCTION dbo.regexp_match
    (
        @source varchar(5000),
        @regexp varchar(1000),
        @ignorecase bit = 0
    )
RETURNS bit
AS
    BEGIN
        DECLARE @hr integer
        DECLARE @objRegExp integer
        DECLARE @objMatches integer
        DECLARE @objMatch integer
        DECLARE @count integer
        DECLARE @results bit
        
        EXEC @hr = sp_OACreate 'VBScript.RegExp', @objRegExp OUTPUT
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END
        EXEC @hr = sp_OASetProperty @objRegExp, 'Pattern', @regexp
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END
        EXEC @hr = sp_OASetProperty @objRegExp, 'Global', false
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END
        EXEC @hr = sp_OASetProperty @objRegExp, 'IgnoreCase', @ignorecase
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END    
        EXEC @hr = sp_OAMethod @objRegExp, 'Test', @results OUTPUT, @source
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END
        EXEC @hr = sp_OADestroy @objRegExp
        IF @hr <> 0 BEGIN
            SET @results = 0
            RETURN @results
        END
    RETURN @results
    END

А использовать её можно так:
Код

SELECT TOP 5 * FROM "myTable" WHERE dbo.regexp_match("myField",'\d{2,3}$',1) = 1

Подробнее об особенностях VBScript.RegExp лучше почитать заранее, чтоб не попасть впросак - некоторые отличия от других(к примеру, POSIX) реализаций имеются.
PM MAIL   Вверх
setnull
Дата 10.12.2007, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



А можно уточнить?
Если поле myField проиндексировано, данный запрос воспользуется этим индексом?
PM MAIL   Вверх
skyboy
Дата 10.12.2007, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 2
Всего: 260



Цитата(setnull @  10.12.2007,  21:41 Найти цитируемый пост)
Если поле myField проиндексировано, данный запрос воспользуется этим индексом? 

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

Добавлено через 15 секунд
Цитата(skyboy @  10.12.2007,  21:59 Найти цитируемый пост)
нет

в смысле - не воспользуется
PM MAIL   Вверх
setnull
Дата 11.12.2007, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



Так если рассматривать не структуру индекса, а алгоритм поиска....

Из страницы индексов отобрать строки, что удовлетворяют регэкспу,
а затем вытянуть соответствующие им записи таблицы...
PM MAIL   Вверх
skyboy
Дата 11.12.2007, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 2
Всего: 260



Цитата(setnull @  11.12.2007,  18:54 Найти цитируемый пост)
Из страницы индексов отобрать строки

так как регулярные выражения - очень гибкий механизм, то подобная страница индексов строилась бы по совпадению/несовпадению с регулярным выражением(так как регулярное выражение может быть и "\d\d", и "^\s.*$"). т.о. сначала строились бы индексы, а потом единократно их использовали бы. смысЛ? я лично не вижу.
единственный смысл был бы при использовании в секции on для join'ов, чтоб несколько раз не вычислять заново значение для незменного аргумента, но, как я понял, детерминистические функции(вызовы с определнными аргументами) и так кешируются, так что в этом отношении все продуманно.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS SQL"
Akina

Akina

Запрещается!

Публиковать ссылки и обсуждать взлом чего бы то ни было.

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы составления неспецифических запросов рассматриваются здесь
  • Используйте теги [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, Akina.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS SQL Server | Следующая тема »


 




[ Время генерации скрипта: 0.0829 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.