Добро пожаловать к нам в гости! Наш сайт посвящён программе NeoBook, с помощью которой вы легко сможете создавать собственные мультимедиа-приложения без необходимости изучать сложные языки программирования! Зарегистрируйтесь, чтобы стать членом нашего сообщества.
Как отделить кавычки встречающиеся в содержимом запроса от кавычек синтаксиса команды поиска?
Или, как сделать так, чтобы поиск работал корректно даже если в запросе есть содержимое с кавычками?
Или, как плагину NeoBookDBPro показать, какие кавычки относятся к синтаксису команды, а какие - просто символы для поиска?
Расшифрую вопрос. Поиск по схеме:
dbpQuery "база" "таблица" "[имя поля] = [переменная для содержимого активной ячейки]"
работает безотказно, НО только до того самого момента, пока в [переменной для содержимого активной ячейки] не обнаруживается запись с кавычками (например, в поле "Организация" оказывается подобная запись: ООО "Заправка в воздухе"). В результате формируется запрос, который некорректно впоследствии прочитывается (прога пишет, что не хватает оператора в запросе (понятное дело, раз кавычки истолковываются как часть синтаксиса самой команды поиска):
Запрос вида:
dbpQuery "Kultura" "Result" "fORGANIZATION = [#34]ООО [#34]Заправка в воздухе[#34][#34]"
приводит к ошибке:
Эски-код [#34] используется для закавычивания строкового запроса, если этого не сделать, то выдаст другую ошибку - на запрос:
dbpQuery "Kultura" "Result" "fORGANIZATION = ООО [#34]Заправка в воздухе[#34]"
выдаст ошибку:
Анализ возможных решений:
1) Не хотелось бы запрещать пользователю использовать кавычки при вводе данных, поскольку многие названия организаций их содержат. И будет некорректно требовать вводить названия без них или заменять их другим символом (но кроме как при вводе данных незаметно от пользователя заменять кавычки на другой символ... - у меня иного решения пока нет...).
2) Замена кавычек перед формированием запроса на эски-код [#34] не дал результата, в запросе все равно потом фигурируют кавычки и NeoBookDBPro учитывает их как часть синтаксиса команды dbpQuery.
3) Автозамена на другие символы или удаление кавычек перед формированием запроса тоже не подходит, поскольку поиск должен осуществляться по буквальному содержимому выделяемой пользователем ячейки таблицы (иначе команда просто не найдет ни одной записи, если вместо существующих записей - ООО "Заправка в воздухе" - будет искать несуществующую в базе запись - ООО Заправка в воздухе).
На данный момент код выглядит так:
Code
.Получаем имя активного поля dbpGetActiveField "Kultura" "Result" "[FieldFullName]" .Применить автофильтр, только если имя поля (столбца) изменилось или содержание ячейки в рамках того же имени поля (столбца) IfEx "[FieldFullName] <> [FieldFullNameNext] OR [FieldSerch] <> [FieldSerchNext]" .Многократный фильтр (поиск по полному совпадению) на основе dbpQuery IfEx "[FieldFullName] <> [#34][#34] AND [Kultura.Result.[FieldFullName]] <> [#34][#34] AND [filterAuto] <> 0" If "[Zapros]" "<>" "" .Получаем содержимое активной ячейки и формируем составной запрос SetVar "[FieldSerch]" "[#34][Kultura.Result.[FieldFullName]][#34]" SetVar "[ZaprosNew]" "[FieldFullName] = [FieldSerch]" SetVar "[Zapros]" "[Zapros] AND [ZaprosNew]" dbpQuery "Kultura" "Result" "[Zapros]" Else .Получаем содержимое активнйо ячейки для случая первого запроса SetVar "[FieldSerch]" "[#34][Kultura.Result.[FieldFullName]][#34]" dbpQuery "Kultura" "Result" "[FieldFullName] = [FieldSerch]" SetVar "[Zapros]" "[FieldFullName] = [FieldSerch]" EndIf SetVar "[FieldSerchNext]" "[Kultura.Result.[FieldFullName]]" SetVar "[FieldFullNameNext]" "[FieldFullName]" Else EndIF Else EndIf
Есть идеи, как научить команду dbpQuery отличать "свои" кавычки от "чужих"?
Когда то символы ' и " попались и мне на пути в MySQL ( правда не знаю какую БД юзаешь ты ), так вот насколько я понял в БД в самих полях спец.символы должны присутствовать только в виде мнемоник http://www.mexxs.net/reviews.php?file=39
в самих полях спец.символы должны присутствовать только в виде мнемоник
Ой! Это что за зверь! Запрос вида dbpQuery "Kultura" "Result" "fORGANIZATION = [#34]ООО "Заправка в воздухе"[#34]" выдает ошибку синтаксиса... Что-то я не так делаю или не то... ip19216811, спасибо за новую инфу! Наверное и применение спец.символов в Access где-то должно быть описано... Надо погуглить...
Добавлено (15 Апрель 2011, 20:50) --------------------------------------------- Э-э... а вот форум принял мнемоники и выдал вместо них (в последнем моем примере) знаки кавычек, так что не видно, что я вместо них применил мнемоники.
Запрос вида dbpQuery "Kultura" "Result" "fORGANIZATION = [#34]ООО "Заправка в воздухе"[#34]"
двойная кавычка это
Code
" или " , а не [#34]
Попробуй отправить запрос так
Code
dbpQuery "Kultura" "Result" "fORGANIZATION = "ООО "Заправка в воздухе"""
или так
Code
dbpQuery "Kultura" "Result" "fORGANIZATION = "ООО "Заправка в воздухе """
Quote (Вадим)
Э-э... а вот форум принял мнемоники и выдал вместо них (в последнем моем примере) знаки кавычек, так что не видно, что я вместо них применил мнемоники.
Елки даже в коде преобразует мнемонику , сейчас текстовичек прикреплю
Не, в NB есть глобальная переменная - [#34] (означает кавычки), она как раз используется тогда, когда нельзя использовать кавычки, чтобы не натолкнуться на проблемы с синтаксисом.
Попробовал примеры из текстовика (спасибо!), но не помогло. И в самой базе видны мнемоники вместо кавычек и поиск выдает ошибки (даже если крайние мнемоники заменить на [#34]).
У меня поле в базе не поддерживает нужного числа символов, поэтому в записях использовал урезанные примеры (без слова "воздухе"): ООО "Заправка в" (так что не обращайте на это внимания).
Добавлено (15 Апрель 2011, 22:00) --------------------------------------------- Если я правильно понял, то если пользователь вводит в поле ввода кавычки, прога при сохранении в базу заменяет их на мнемоники и хранит в базе в таком виде, верно?
Не, в NB есть глобальная переменная - [#34] (означает кавычки), она как раз используется тогда, когда нельзя использовать кавычки, чтобы не натолкнуться на проблемы с синтаксисом.
просто по аналогии с MySQL посоветовал, в нем внутри полей вместо символов которые используются для указания полей должны быть заменены на мнемонику, по этому скорее всего и в данном случае есть какой то заменитель но наверное не вида [#34], сам по суди вдруг ты эту БД будешь просматривать не с помощью своей программы и код [#34] будет выведен не в виде двойной кавычки, а как [#34]. Вот тут походу http://forum.ixbt.com/topic.cgi?id=26:39429 кто то уже ломал голову над этим, и самый простой выход ему советовали заменить двойные кавычки одинарными
Если я правильно понял, то если пользователь вводит в поле ввода кавычки, прога при сохранении в базу заменяет их на мнемоники и хранит в базе в таком виде, верно?
В MySQL да, так как иначе потом при импорте MySQL дампа будут косяки, и тут либо как написано в ссылке выше поступи (там замени на одинарные кавычки, или кавычки являющиеся частью данных удвой как показано в примере там же) или же рой инфу
Сообщение отредактировано ip19216811 - Пт, 15 Апреля 2011, 22:19
Вадим, здесь наверно тебе как раз и сможет помочь SQL запрос. Тереби Юру. Попробуй еще заключит в (). мож поможет, хотя вряд ли. Не хочешь читать хелп?
Зашёл сюда на минутку. Подробно не вникал в тему, но обычно двойные кавычки экранируются, чтобы отделиться от строки самого запроса. Делается это с помощью слэша:
Еще что можно попробовать. У тебя эти поля типа строкового? Переназначить поля и сделать их МЕМО. Тогда при поиске не надо будет заключать в кавычки. Может быть так и прокатит. Не хочешь читать хелп?
dbpExecSQL "Kultura" "SELECT * FROM Result WHERE fORGANIZATION = ООО \"Заправка в воздухе\"" ""
вызывает у дебаггера удивление, в отношении третьего параметра.
Как и такой запрос:
.dbpExecSQL "Kultura" "SELECT * FROM Result WHERE fORGANIZATION = [#34]ООО \"Заправка в воздухе\"[#34]" ""
Quote (mishem)
Попробуй еще заключит в ()
Попробовал и это, заключил кавычки самих данных в скобки - не помогло.
Но ведь должны же они как-то экранироваться то в конце концов!
Quote (mishem)
У тебя эти поля типа строкового? Переназначить поля и сделать их МЕМО.
Да, строкового. Сейчас попробую!
Добавлено (15 Апрель 2011, 23:21) --------------------------------------------- mishem, с memo тоже не прокатило. Результат такой же в точности, как и с типом string (пишет, что не хватает оператора, т.е. видит кавычки как управляющие символы, а не просто как часть данных...).
Вадим, попробуй одинарные кавычки, может прокатит, чет помню с мускулом вроде прокатывало. А мож еще попробуй через переменную, да и почитай какофф синтаксис и правила написания sql в применяемой базе.
Вадим, я тоже бодался с такой бедой, сейчас не помню чем закончилось решение, но вроде эта беда самаго плагина. Толи он удаляет слеши, то ли слешует еще раз сам, короче вывод я сделал такой: что вся замарока в плагине и его обработка твоих sql запросов, т.к. в пхп подобный запрос со слешами проходит без проблем. Как обошел этот момент не помню Возможно, через функцию Петра StrToAsii, помню, что применял, но оставил или нет незнаю Либо с подменой ковычек на другие символы...
Спасибо, Alex3A! Прокатывает с апострофом ('), в т.ч. двойным ('') и обратным апострофом (`), в т.ч. двойным (``):
dbpQuery "Kultura" "Result" "fORGANIZATION = [#34]ООО ''Заправка в воздухе''[#34]"
dbpQuery "Kultura" "Result" "fORGANIZATION = [#34]ООО ``Заправка в воздухе``[#34]"
Причем dbpQuery работает точно также как и dbpExecSQL.
В случае с двойным апострофом вообще для пользователя разницы никакой не будет, это замечательно! Нужно будет лишь организовать автозамену при вводе - если двойные кавычки, то заменять на двойной апостроф. Таким образом в базу попадут не реальные кавычки, а два апострофа вместо каждой двойной кавычки. По крайней мере, это пока единственный рабочий способ - позволяет сохранить (хотя бы визуально) кавычки и осуществлять поиск с использованием данных содержащих такие "квазикавычки".
Попытки же экранировать реальный кавычки в самих данных (при запросе) не удаются (я почему-то решил, что обрабатывать в запросе в данном случае правильнее всего, с точки зрения универсальности работы с данными - не подделываем данные под специфику своей проги).
Но может я что не так делал... Попробовал варианты запросов (предполагая найти запись: ООО "Заправка в воздухе"):
обязан быть такой способ, ты еще раз пошерсти в гугле, там народ тоже интересуется
Пошерстим, почешем, авось вычешем...
По первой ссылке не смог выйти на тему, полупустую страницу показывает с текстом:
There is currently no text in this page, you can search for this page title in other pages or edit this page. Disclaimer: IT Wiki is a service that allows content to be created and edited by anyone in the community. Content posted to this site is not reviewed for correctness and is not supported by Toolbox.com or any of its partners. If you feel a wiki article is inappropriate, you can either correct it by clicking "Edit" above or click here to notify Toolbox.com.
Quote (DEMBEL)
еще попробуй каждую одинарную кавычку заменить двойной
Это не понял, расшифруй, если не трудно. В базу сейчас идут итак двойные, если после ввода пользователем ничего с ними не делать. Соответственно при запросе нечего менять - одинарных нет.
Quote (DEMBEL)
типа FROM Result WHERE fORGANIZATION = "ООО ""Заправка в воздухе""" замени на #34 либо только крайние кавычки самого запроса, либо вообще все.
А, вот ты о чем. Нет, я всё это перепробовал, прежде чем вопрос на форуме запостить. И все эски-коды перепробовал - с прямыми, обратными и вывернутыми наизнанку кавычками На твой запрос прога скажет: "третий параметр не содержит оператор".
Добавлено (18 Апрель 2011, 00:49) --------------------------------------------- первый раз такое вижу, ссылка не открывается с другого домена...
Добавлено (18 Апрель 2011, 00:50) --------------------------------------------- поищи по сайту на предмет How do I escape single quotes in SQL queries?
поищи по сайту на предмет How do I escape single quotes in SQL queries?
ОК!
Добавлено (18 Апрель 2011, 01:24) --------------------------------------------- Там приводится следующее решение (удвоение кавычек):
"Это строка, которая включает в себя" "текст в кавычках" "в середине"
"Это строка, которая заканчивается" "текстом в кавычках" ""
Но в NB это не прокатывает. Кавычки однозначно трактуются как управляющий символ. Например, вызывают ошибку в третьем параметре следующие запросы (обрамление в [#34] требуется, поскольку строковые данные содержат пробел):
dbpExecSQL "Kultura" "SELECT * FROM Result WHERE fORGANIZATION = [#34]ООО ""Заправка в воздухе""[#34]" ""
dbpExecSQL "Kultura" "SELECT * FROM Result WHERE fORGANIZATION = [#34]ООО ""Заправка в воздухе"[#34]" ""
Но раз должен (по логике вещей) быть экранирующий символ, то остается видимо проверить эту гипотезу простым перебором всех символов, подставляя их перед двойной кавычкой...
Как делать параметрический запрос я не врубился...
Может быть еще есть способ с функциями "реплейс" в запросе, но как с ними работать мне тоже непонятно пока что...
Наверное нужно просто задавать вопрос разработчикам NB о том, как экранировать кавычки и другие спецсимволы...
Наверное нужно просто задавать вопрос разработчикам NB
Ура!!! Разрабы ответили (да хранят их небо и добрые люди!!), решение оказалось до смешного простым . Наверное единственный вариант, какой я не пробовал (и лишь потому, что оголтело следовал инструкциям в справке). Оказывается, нужно всё содержимое активной ячейки помещать в одинарные кавычки (не зря про них Алекс вспоминал!), а глобальную переменную [#34] использовать для того, чтобы закодировать кавычки, имеющиеся в самих данных:
Например, чтобы найти запись ООО "Заправка в воздухе" запрос будет выглядеть так:
dbpQuery "Kultura" "Result" "fORGANIZATION = 'ООО [#34]Заправка в воздухе[#34]'"
При динамическом формировании составного запроса (чтобы работало "наложение фильтров"), это означает, что нужно будет составлять запрос с учетом содержимого (если в переменной активной ячейки есть кавычки, то заменять их на глобальную переменную [#34] и помещать всё содержимое в одинарные кавычки (апостроф):
Code
.Проверяем наличие двойных кавычек SearchStr "[#34]" "[Kultura.Result.[FieldFullName]]" "[guoteYes]" "" .Если их нет If "[guoteYes]" "=" "0" .Получаем содержимое активной ячейки и формируем составной запрос SetVar "[FieldSerch]" "[#34][Kultura.Result.[FieldFullName]][#34]" SetVar "[ZaprosNew]" "[FieldFullName] = [FieldSerch]" SetVar "[Zapros]" "[Zapros] AND [ZaprosNew]" dbpQuery "Kultura" "Result" "[Zapros]" Else .Если кавычки есть, то заменяем их на глобальную переменную (выглядит тут тавтологично, поскольку заменяем [#34] на [#34], но это только видимость). SetVar "[FieldSerch]" "[Kultura.Result.[FieldFullName]]" StrReplace "[FieldSerch]" "[#34]" "[#34]" "[FieldSerch]" "" .Добавляем одинарные кавычки (апострофы) SetVar "[ZaprosNew]" "[FieldFullName] = '[FieldSerch]'" SetVar "[Zapros]" "[Zapros] AND [ZaprosNew]" dbpQuery "Kultura" "Result" "[Zapros]" EndIf
Оказывается, нужно всё содержимое активной ячейки помещать в одинарные кавычки (не зря про них Алекс вспоминал!),
Подобное встречается в некоторых языках програмирования, в том же php, где текст между одними кавычками интерпритируется, а между другими нет, по этому и послал тебя изучать синтаксис. В системах с разным синтаксисом нужно еще поизголятся, пока составиш строку удовлетворяющую и одного и другого.
Обнаружился важный нюанс с обработкой кавычек в поисковом запросе, а именно, когда нужно применить подстановочный символ "%".
Хочу поделиться решением. Может сэкономит кому-то несколько часов жизни
Если запрос содержит кавычки (которые как было показано выше нужно в таком случае заменить на [#34]) и, кроме того, если нужно использовать оператор LIKE с подстановочным символом %, то не следует применять глобальную переменную [#34] для закавычивания запроса ([#34]%[findX]%[#34]), вместо нее необходимо использовать одинарные кавычки ('%[findX]%').
Code
[FieldFind] - выбранное пользователем поле таблицы, в котором осуществляется поиск. [findX] - введенные пользователем символы для поиска.
.Многократный фильтр на основе dbpQuery (с обработкой ввода кавычек) IfEx "[FieldFind] <> [#34][#34] AND [findX] <> [#34][#34]" SearchStr "[#34]" "[findX]" "[guoteYes]" "" .Если кавычек в запросе нет If "[guoteYes]" "=" "0" If "[Zapros]" "<>" "" SetVar "[ZaprosNew]" "[FieldFind] LIKE [#34]%[findX]%[#34]" SetVar "[Zapros]" "[Zapros] AND [ZaprosNew]" dbpQuery "Kultura" "Result" "[Zapros]" Else dbpQuery "Kultura" "Result" "[FieldFind] LIKE [#34]%[findX]%[#34]" SetVar "[Zapros]" "[FieldFind] LIKE [#34]%[findX]%[#34]" EndIf Else .Раз кавычки в запросе есть, то заменяем их на [#34] StrReplace "[findX]" "[#34]" "[#34]" "[findX]" "" If "[Zapros]" "<>" "" .Формируем запрос с одинарными кавычками SetVar "[ZaprosNew]" "[FieldFind] LIKE '%[findX]%'" SetVar "[Zapros]" "[Zapros] AND [ZaprosNew]" dbpQuery "Kultura" "Result" "[Zapros]" Else SetVar "[Zapros]" "[FieldFind] LIKE '%[findX]%'" dbpQuery "Kultura" "Result" "[Zapros]" EndIf EndIf EndIf