powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Экранирование строк перед подстановкой в SQL-запрос
21 сообщений из 21, страница 1 из 1
Экранирование строк перед подстановкой в SQL-запрос
    #36637439
smagen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть ли в Cache функция, которая бы экранировала символы строки перед её подстановкой в динамически-формируемый SQL-запрос?
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36637507
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поясните
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36637562
smagen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть строка. Мне надо подставить её в SQL запрос. Для того, чтобы это сделать, надо заключить её в кавычки и заэкранировать специальные символы (например, те же кавычки). (PreparedStatement в данном случае не подходит) Как это сделать в Cache?
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36637705
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не полностью уверен, но кажется может подойти
$$Quote^%cspQuote(str)
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36637719
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smagen , в SQl двойные кавычки можно заменить на одинарные...
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36638223
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в Cache параметры для sql можно передавать отдельно, и там необязательно экранирование
в плане безопасности, связанная она в частности с sql-инъекциями, динамически формируемый запрос с подстановкой параметров поиска прямо в запрос очень, небезопасно
поэтому лучше передавать их отдельно
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36638329
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в строке встречаются ковычки с апострофами - то IMXO никак.
Код: plaintext
1.
w "'"_$REPLACE($ZCVT("Моя любимая"" строка","O","JS"),"\""","""")_"'"
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36638380
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автор хоть бы показал как он этот sql-запрос обрабатывает...
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641649
smagen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну яНе полностью уверен, но кажется может подойти
$$Quote^%cspQuote(str)
Спасибо. Но судя по названию, не совсем то, что нужно.
krvsa smagen , в SQl двойные кавычки можно заменить на одинарные...
Не совсем понял, чем мне это поможет.
DAiMorв Cache параметры для sql можно передавать отдельно, и там необязательно экранирование
в плане безопасности, связанная она в частности с sql-инъекциями, динамически формируемый запрос с подстановкой параметров поиска прямо в запрос очень, небезопасно
поэтому лучше передавать их отдельно
Спасибо, капитан очевидность. Именно потому, что прямая подстановка строки в sql приводит к sql-инъекции, мне требуется заэкранировать там спецспиволы. :)
PtnЕсли в строке встречаются ковычки с апострофами - то IMXO никак.
Код: plaintext
1.
w "'"_$REPLACE($ZCVT("Моя любимая"" строка","O","JS"),"\""","""")_"'"

Это выглядит ближе всего к тому, что нужно, хотя я расчитываел, что в Cache есть встроенная функция для решения этой задачи.
krvsaАвтор хоть бы показал как он этот sql-запрос обрабатывает...
Я считал что описанная задача тривиальна и поэтому детальное описание ситуации, в которой она возникает, не нужно.
Вообще, я сильно удивлён. Какие бы до этого средства разработки и СУБД я ни использовал, функция, которая экранирует спецсимволы SQL запросто находилась в документации. С Cache же я не только не смог найти её самостоятельно, но даже запостив сообщение на форум, получил вместо простого ответа вроде "$$$SqlEscape, а вообще-то автору не мешало бы научиться пользоваться поиском", целый ряд комментариев, которые оставляют больше вопросов, чем ответов.
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641714
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дело в том, что в каше нет смысла экранировать символы, поэтому и нету такого функционала
нужно передавать параметрами отдельно
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641769
smagen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMorдело в том, что в каше нет смысла экранировать символы, поэтому и нету такого функционала
нужно передавать параметрами отдельно
Очень спорно. Про Cache я точно не знаю, а других базах есть сильное отличие между передачей параметров в prepared statement и подстановкой их напрямую в sql. Для prepared statement один раз строится план и дальше он уже исполняется с различными параметрами. А когда параметры напрямую подставляются в sql, то планировщик составляет план с учётом конкретных значений параметров, и этот план может радикально отличаться в лучшую сторону. Поэтому нужны оба способа подстановки параметров.
Метод Execute класса %Library.ResultSet - отдельная песня. Почему нет возможности передавать параметры запроса как массив, а только как параметры метода? Почему их количество ограничено 16?! 640кб памяти хватит всем? :)
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641798
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smagenЯ считал что описанная задача тривиальна и поэтому детальное описание ситуации, в которой она возникает, не нужно.
Т.е. примера мы и не увидим...
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641804
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smagenМетод Execute класса %Library.ResultSet - отдельная песня. Почему нет возможности передавать параметры запроса как массив, а только как параметры метода? Почему их количество ограничено 16?! 640кб памяти хватит всем? :)
А ты письмо гневное напиши в ИС. А мы подпишемся...
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641813
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
отказываясь передавать параметрами вы себе еще больше гемора доставляете
а насчет того что, такой запрос будет быстрее выполняться, по-моему нет, для этого можно сравнить генерируемый код, и уверен, что отличий не будет

и %Library.ResultSet устарел при использовании с динамическими запросами
пора переходить на %ResultSet.SQL он и работает значительно быстрее
и параметры в него можно передавать массивом
ограничения по передаче параметров выше
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641854
smagen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMorотказываясь передавать параметрами вы себе еще больше гемора доставляете
а насчет того что, такой запрос будет быстрее выполняться, по-моему нет, для этого можно сравнить генерируемый код, и уверен, что отличий не будет
Очень может быть, что Вы здесь правы. Я пока не проводил тесты, но по субъективным впечатлениям в Cache слабый планировщик, скорее всего он этого не учитывает.
DAiMorи %Library.ResultSet устарел при использовании с динамическими запросами
пора переходить на %ResultSet.SQL он и работает значительно быстрее
и параметры в него можно передавать массивом
ограничения по передаче параметров выше
Спасибо за наводку, буду изучать!
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36641857
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMorотказываясь передавать параметрами вы себе еще больше гемора доставляете
а насчет того что, такой запрос будет быстрее выполняться, по-моему нет, для этого можно сравнить генерируемый код, и уверен, что отличий не будет

и %Library.ResultSet устарел при использовании с динамическими запросами
пора переходить на %ResultSet.SQL он и работает значительно быстрее
и параметры в него можно передавать массивом
ограничения по передаче параметров выше
а не ошибся параметры нельзя массивом передавать, но зато там из можно передать больше 200
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36642291
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smagenДля prepared statement один раз строится план и дальше он уже исполняется с различными параметрами. А когда параметры напрямую подставляются в sql, то планировщик составляет план с учётом конкретных значений параметров, и этот план может радикально отличаться в лучшую сторону. Поэтому нужны оба способа подстановки параметров.
Кэш Запросов

Запрос:
Код: plaintext
1.
select * from table where field= 1 
закэшируется в
Код: plaintext
1.
select * from table where field=?
,поэтому уже другой запрос
Код: plaintext
1.
select * from table where field= 5719 
будет использовать ранее подготовленный запрос. Это легко проверить в Портале.
При сборе статистики по таблице, а также при других обстоятельствах, ранее закэшированные запросы удаляются.

Поэтому формировать текст запроса:
Код: plaintext
set sql="select * from table where id='"_нечто_"'"
не имеет смысла. К тому же, как выше справедливо заметили, это небезопасно.

PS: если Вы используете версию 2010.1 и выше, то предпочтительней пользоваться классом %SQL.Statement вместо %ResultSet.SQL и %Library.ResultSet .
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36642400
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMorа не ошибся параметры нельзя массивом передавать
Можно ;)

Собираем параметры
Код: plaintext
1.
 s params=$i(params), params(params)=arg
И передаем массивом
Код: 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.
/// Возвращает объект %ResultSet.SQL
/// для запроса <var>sql</var>, c массивом параметров <var>params</var>
/// возможно вернет ошибку <var>err</var> 
ClassMethod GetResultSetSQL(sql As %String, ByRef params As %String, ByRef err As %String = "") As %ResultSet.SQL
{
	 s rs=##class(%ResultSet.SQL).%Prepare(.sql,.err,""
	 	,$g(params( 1 )),$g(params( 2 )),$g(params( 3 )),$g(params( 4 )),$g(params( 5 )),$g(params( 6 )),$g(params( 7 )),$g(params( 8 )),$g(params( 9 )),$g(params( 10 ))
	 	,$g(params( 11 )),$g(params( 12 )),$g(params( 13 )),$g(params( 14 )),$g(params( 15 )),$g(params( 16 )),$g(params( 17 )),$g(params( 18 )),$g(params( 19 )),$g(params( 20 ))
	 	,$g(params( 21 )),$g(params( 22 )),$g(params( 23 )),$g(params( 24 )),$g(params( 25 )),$g(params( 26 )),$g(params( 27 )),$g(params( 28 )),$g(params( 29 )),$g(params( 30 ))
	 	,$g(params( 31 )),$g(params( 32 )),$g(params( 33 )),$g(params( 34 )),$g(params( 35 )),$g(params( 36 )),$g(params( 37 )),$g(params( 38 )),$g(params( 39 )),$g(params( 40 ))
	 	,$g(params( 41 )),$g(params( 42 )),$g(params( 43 )),$g(params( 44 )),$g(params( 45 )),$g(params( 46 )),$g(params( 47 )),$g(params( 48 )),$g(params( 49 )),$g(params( 50 ))
	 	,$g(params( 51 )),$g(params( 52 )),$g(params( 53 )),$g(params( 54 )),$g(params( 55 )),$g(params( 56 )),$g(params( 57 )),$g(params( 58 )),$g(params( 59 )),$g(params( 60 ))
	 	,$g(params( 61 )),$g(params( 62 )),$g(params( 63 )),$g(params( 64 )),$g(params( 65 )),$g(params( 66 )),$g(params( 67 )),$g(params( 68 )),$g(params( 69 )),$g(params( 70 ))
	 	,$g(params( 71 )),$g(params( 72 )),$g(params( 73 )),$g(params( 74 )),$g(params( 75 )),$g(params( 76 )),$g(params( 77 )),$g(params( 78 )),$g(params( 79 )),$g(params( 80 ))
	 	,$g(params( 81 )),$g(params( 82 )),$g(params( 83 )),$g(params( 84 )),$g(params( 85 )),$g(params( 86 )),$g(params( 87 )),$g(params( 88 )),$g(params( 89 )),$g(params( 90 ))
	 	,$g(params( 91 )),$g(params( 92 )),$g(params( 93 )),$g(params( 94 )),$g(params( 95 )),$g(params( 96 )),$g(params( 97 )),$g(params( 98 )),$g(params( 99 )),$g(params( 100 ))
	 	,$g(params( 101 )),$g(params( 102 )),$g(params( 103 )),$g(params( 104 )),$g(params( 105 )),$g(params( 106 )),$g(params( 107 )),$g(params( 108 )),$g(params( 109 )),$g(params( 110 ))
	 	,$g(params( 111 )),$g(params( 112 )),$g(params( 113 )),$g(params( 114 )),$g(params( 115 )),$g(params( 116 )),$g(params( 117 )),$g(params( 118 )),$g(params( 119 )),$g(params( 120 ))
	 	,$g(params( 121 )),$g(params( 122 )),$g(params( 123 )),$g(params( 124 )),$g(params( 125 )),$g(params( 126 )),$g(params( 127 )),$g(params( 128 )),$g(params( 129 )),$g(params( 130 ))
	 	,$g(params( 131 )),$g(params( 132 )),$g(params( 133 )),$g(params( 134 )),$g(params( 135 )),$g(params( 136 )),$g(params( 137 )),$g(params( 138 )),$g(params( 139 )),$g(params( 140 ))
	 	,$g(params( 141 )),$g(params( 142 )),$g(params( 143 )),$g(params( 144 )),$g(params( 145 )),$g(params( 146 )),$g(params( 147 )),$g(params( 148 )),$g(params( 149 )),$g(params( 150 ))
	 	,$g(params( 151 )),$g(params( 152 )),$g(params( 153 )),$g(params( 154 )),$g(params( 155 )),$g(params( 156 )),$g(params( 157 )),$g(params( 158 )),$g(params( 159 )),$g(params( 160 ))
	 	,$g(params( 161 )),$g(params( 162 )),$g(params( 163 )),$g(params( 164 )),$g(params( 165 )),$g(params( 166 )),$g(params( 167 )),$g(params( 168 )),$g(params( 169 )),$g(params( 170 ))
	 	,$g(params( 171 )),$g(params( 172 )),$g(params( 173 )),$g(params( 174 )),$g(params( 175 )),$g(params( 176 )),$g(params( 177 )),$g(params( 178 )),$g(params( 179 )),$g(params( 180 ))
	 	,$g(params( 181 )),$g(params( 182 )),$g(params( 183 )),$g(params( 184 )),$g(params( 185 )),$g(params( 186 )),$g(params( 187 )),$g(params( 188 )),$g(params( 189 )),$g(params( 190 ))
	 	,$g(params( 191 )),$g(params( 192 )),$g(params( 193 )),$g(params( 194 )),$g(params( 195 )),$g(params( 196 )),$g(params( 197 )),$g(params( 198 )),$g(params( 199 )),$g(params( 200 ))	 	
		,$g(params( 201 )),$g(params( 202 )),$g(params( 203 )),$g(params( 204 )),$g(params( 205 )),$g(params( 206 )),$g(params( 207 )),$g(params( 208 )),$g(params( 209 )),$g(params( 210 ))
	 	,$g(params( 211 )),$g(params( 212 )),$g(params( 213 )),$g(params( 214 )),$g(params( 215 )),$g(params( 216 )),$g(params( 217 )),$g(params( 218 )),$g(params( 219 )),$g(params( 220 ))
	 	,$g(params( 221 )),$g(params( 222 )),$g(params( 223 )),$g(params( 224 )),$g(params( 225 )),$g(params( 226 )),$g(params( 227 )),$g(params( 228 )),$g(params( 229 )),$g(params( 230 ))
	 	,$g(params( 231 )),$g(params( 232 )),$g(params( 233 )),$g(params( 234 )),$g(params( 235 )),$g(params( 236 )),$g(params( 237 )),$g(params( 238 )),$g(params( 239 )),$g(params( 240 ))
	 	,$g(params( 241 )),$g(params( 242 )),$g(params( 243 )),$g(params( 244 )),$g(params( 245 )),$g(params( 246 )),$g(params( 247 )),$g(params( 248 )),$g(params( 249 )),$g(params( 250 ))
	 	,$g(params( 251 ))
	 )
	Q rs
}
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36642426
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я имел ввиду стандартным способом
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36642444
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и если уж на то пошло то тогда уж вот так :)
Код: plaintext
1.
2.
3.
4.
5.
6.
ClassMethod GetResultSetSQL(sql As %String, ByRef params As %String, ByRef err As %String = "") As %ResultSet.SQL [ CodeMode = objectgenerator ]
{
	 d %code.Write(" s rs=##class(%ResultSet.SQL).%Prepare(.sql,.err,""""")
	 f i= 1 : 1 : 251  d %code.Write(",$g(params("_i_"))")
	 d %code.Write(")")
}
так хоть кода поменьше, а результат тот же
...
Рейтинг: 0 / 0
Экранирование строк перед подстановкой в SQL-запрос
    #36644122
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну раз пошла такая пьянка то вообще то можно напрямую указывать переменные
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
set params( 1 )= 5 
set params( 3 )= 0 
set rs=##class(%ResultSet).%New()
do rs.Prepare("select * from SomeTable where Code=:params(1) and State=:params(3)")
do rs.Execute()
while rs.Next() {
    write rs.Get("ID")
} do rs.Close() set rs=""

В принципе будет работать
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Экранирование строк перед подстановкой в SQL-запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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