Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Экранирование строк перед подстановкой в SQL-запрос / 21 сообщений из 21, страница 1 из 1
19.05.2010, 17:47
    #36637439
smagen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
Есть ли в Cache функция, которая бы экранировала символы строки перед её подстановкой в динамически-формируемый SQL-запрос?
...
Рейтинг: 0 / 0
19.05.2010, 18:14
    #36637507
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
поясните
...
Рейтинг: 0 / 0
19.05.2010, 18:48
    #36637562
smagen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
У меня есть строка. Мне надо подставить её в SQL запрос. Для того, чтобы это сделать, надо заключить её в кавычки и заэкранировать специальные символы (например, те же кавычки). (PreparedStatement в данном случае не подходит) Как это сделать в Cache?
...
Рейтинг: 0 / 0
19.05.2010, 20:06
    #36637705
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
Не полностью уверен, но кажется может подойти
$$Quote^%cspQuote(str)
...
Рейтинг: 0 / 0
19.05.2010, 20:17
    #36637719
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
smagen , в SQl двойные кавычки можно заменить на одинарные...
...
Рейтинг: 0 / 0
20.05.2010, 08:18
    #36638223
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
в Cache параметры для sql можно передавать отдельно, и там необязательно экранирование
в плане безопасности, связанная она в частности с sql-инъекциями, динамически формируемый запрос с подстановкой параметров поиска прямо в запрос очень, небезопасно
поэтому лучше передавать их отдельно
...
Рейтинг: 0 / 0
20.05.2010, 09:23
    #36638329
Ptn
Ptn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
Если в строке встречаются ковычки с апострофами - то IMXO никак.
Код: plaintext
1.
w "'"_$REPLACE($ZCVT("Моя любимая"" строка","O","JS"),"\""","""")_"'"
...
Рейтинг: 0 / 0
20.05.2010, 09:55
    #36638380
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
Автор хоть бы показал как он этот sql-запрос обрабатывает...
...
Рейтинг: 0 / 0
21.05.2010, 14:31
    #36641649
smagen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
ну яНе полностью уверен, но кажется может подойти
$$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
21.05.2010, 14:51
    #36641714
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
дело в том, что в каше нет смысла экранировать символы, поэтому и нету такого функционала
нужно передавать параметрами отдельно
...
Рейтинг: 0 / 0
21.05.2010, 15:04
    #36641769
smagen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
DAiMorдело в том, что в каше нет смысла экранировать символы, поэтому и нету такого функционала
нужно передавать параметрами отдельно
Очень спорно. Про Cache я точно не знаю, а других базах есть сильное отличие между передачей параметров в prepared statement и подстановкой их напрямую в sql. Для prepared statement один раз строится план и дальше он уже исполняется с различными параметрами. А когда параметры напрямую подставляются в sql, то планировщик составляет план с учётом конкретных значений параметров, и этот план может радикально отличаться в лучшую сторону. Поэтому нужны оба способа подстановки параметров.
Метод Execute класса %Library.ResultSet - отдельная песня. Почему нет возможности передавать параметры запроса как массив, а только как параметры метода? Почему их количество ограничено 16?! 640кб памяти хватит всем? :)
...
Рейтинг: 0 / 0
21.05.2010, 15:10
    #36641798
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
smagenЯ считал что описанная задача тривиальна и поэтому детальное описание ситуации, в которой она возникает, не нужно.
Т.е. примера мы и не увидим...
...
Рейтинг: 0 / 0
21.05.2010, 15:12
    #36641804
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
smagenМетод Execute класса %Library.ResultSet - отдельная песня. Почему нет возможности передавать параметры запроса как массив, а только как параметры метода? Почему их количество ограничено 16?! 640кб памяти хватит всем? :)
А ты письмо гневное напиши в ИС. А мы подпишемся...
...
Рейтинг: 0 / 0
21.05.2010, 15:15
    #36641813
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
отказываясь передавать параметрами вы себе еще больше гемора доставляете
а насчет того что, такой запрос будет быстрее выполняться, по-моему нет, для этого можно сравнить генерируемый код, и уверен, что отличий не будет

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

и %Library.ResultSet устарел при использовании с динамическими запросами
пора переходить на %ResultSet.SQL он и работает значительно быстрее
и параметры в него можно передавать массивом
ограничения по передаче параметров выше
а не ошибся параметры нельзя массивом передавать, но зато там из можно передать больше 200
...
Рейтинг: 0 / 0
21.05.2010, 17:44
    #36642291
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
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
21.05.2010, 18:38
    #36642400
doublefint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
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
21.05.2010, 18:57
    #36642426
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
я имел ввиду стандартным способом
...
Рейтинг: 0 / 0
21.05.2010, 19:08
    #36642444
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
и если уж на то пошло то тогда уж вот так :)
Код: 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
23.05.2010, 20:16
    #36644122
Ptn
Ptn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Экранирование строк перед подстановкой в SQL-запрос
Ну раз пошла такая пьянка то вообще то можно напрямую указывать переменные
Код: 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
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Экранирование строк перед подстановкой в SQL-запрос / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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