Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите вставить неформатированный текст / 12 сообщений из 12, страница 1 из 1
02.11.2006, 16:00
    #34101470
Robert Ayrapetyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Имеется код вида:

wsprintf(lpOut, "INSERT INTO table_log VALUES (%s)", lpIn);
res = PQexec(conn, lpOut);

lpOut после wsprintf содержит нечто вида:
'1234', 'c:\windows', '123'

Есесно в таблице c:\windows превращается в cwindows.

Вообщем, как заставить вставлять текст "как он есть"? Ручной парсинг не предлагать.
...
Рейтинг: 0 / 0
02.11.2006, 16:11
    #34101530
.gc
.gc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
1. Использовать PQexecParams
2. В случае PQexec использовать PQescapeString
...
Рейтинг: 0 / 0
02.11.2006, 17:04
    #34101755
Robert Ayrapetyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
PQescapeString строку вида
Код: plaintext
'abcd', '123', 'c:\windows'
превращает почему-то в
Код: plaintext
''abcd'', ''123'', ''c:\\windows''
а это не то. Что я делаю не так?
...
Рейтинг: 0 / 0
02.11.2006, 17:51
    #34101959
.gc
.gc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
угу, значит,
Код: plaintext
wsprintf(lpOut, "INSERT INTO table_log VALUES (%s)", lpIn);
а в lpIn -
Код: plaintext
'abcd', '123', 'c:\windows'
ИМХО, дурость это, в смысле - пример плохой практики

постарайтесь разучиться ТАК писать когда дойдете до production версии.

Нормальный код был бы примерно следующий (звыняйте за очепятки, редко C пользую):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
char * quoted_str;
size_t quoted_buf_size, original_str_size, bytes_out;

original_str_size = strlen(original_str);
quoted_buf_size =  2 *original_str_size+ 2 + 1 ; // twice as much for possible escapes +  2  quotes + zero-terminator
quoted_str = alloca(quoted_buf_size);
PQescapeString(quoted_str, original_str, original_str_size);
bytes_out = snprintf(query_buf, query_buf_capacity,  "INSERT INTO table_log (field1, field2) VALUES ( %d, %s )", int_param_1, quoted_str);
if( bytes_out < query_buf_max_len) {
  result = PQexec(conn, query_buf);
} else {
   error("SQL truncation attack detected!");
}
...
Рейтинг: 0 / 0
02.11.2006, 18:00
    #34102004
Robert Ayrapetyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
блин, да объясните толком. original_str у вас в каком виде? Просто разделение запятыми? Если да - это вызовет ошибку на PQexec, т.к. PQescapeString не обрамляет одинарными кавычками параметры для INSERT.
...
Рейтинг: 0 / 0
02.11.2006, 18:06
    #34102020
Robert Ayrapetyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
а, я понял - вы написали для конкретного случая (причем забыли кавычки для %s). Мне такое не подходит - каждый SQL запрос у меня содержит разное кол-во параметров. Писать для каждого свой шаблон нет возможности и желания.
...
Рейтинг: 0 / 0
02.11.2006, 18:29
    #34102088
.gc
.gc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Robert Ayrapetyanа, я понял - вы написали для конкретного случая (причем забыли кавычки для %s). Мне такое не подходит - каждый SQL запрос у меня содержит разное кол-во параметров. Писать для каждого свой шаблон нет возможности и желания.
упс, да, кавычки забыл
Тогда - экранировать каждый элемент в отдельности перед тем, как слить их одну строку с кавычками и запятыми (или у вас данные сразу такими строками в программу попадают?)
И PQexecParams, видно тоже не подходит?:
Код: plaintext
1.
2.
3.
4.
// char * paramStrings[] = {"asdf", "123", "c:\\windows"};
PQexecParams(conn, 
  "INSERT INTO table_name (field_name1, field_name2, field_name3) VALUES ($1, $2, $3)",  
    3 , NULL, paramStrings, NULL, NULL,  0 );
...
Рейтинг: 0 / 0
03.11.2006, 11:14
    #34103319
Robert Ayrapetyan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Код: plaintext
"INSERT INTO table_name (field_name1, field_name2, field_name3) VALUES ($1, $2, $3)"
не подходит, т.к. у меня от 0 до 32 параметров может быть. Писать 32 шаблона не хочу. Неужели нельзя это просто сделать? Ведь проблема именно в том, что PQEscapeString предваряет все одинарные кавычки еще одними одинарными кавчками (непонятно за каким Х).
Насчет "в каком виде попадает строка в программу" - в каком я сам пожелаю. Т.е. это вообще не проблема.
...
Рейтинг: 0 / 0
03.11.2006, 11:27
    #34103381
st_serg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
нашел в доке, только вот чтото смысл не догоню :)
28.3.4. Escaping Strings for Inclusion in SQL Commands
...
The single quotes that must surround PostgreSQL string literals are not included in the result string; they should be provided in the SQL command that the result is inserted into.

ну и так, для информации.

PQescapeString is an older, deprecated version of PQescapeStringConn;the difference is that it does not take conn or error parameters. Because of this, it cannot adjust its behavior depending on the connection properties (such as character encoding) and therefore it may give the wrong results. Also, it has no way to report error conditions.
...
Рейтинг: 0 / 0
03.11.2006, 11:37
    #34103450
.gc
.gc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Гм, а написать ф-ю со следующей спецификацией для формирования шаблонов тоже лень:
Код: plaintext
1.
2.
3.
4.
5.
6.
// OUT: в tmp_buf строка типа "INSERT INTO table_name VALUES ($1, $2 , $3)"
// IN:
//    char * tmp_buf - указатель на память достаточную для формирования строки 
//    char * table_name - имя таблицы, кот. будет вставлено
//    int    param_count - кол-во параметров
void mk_template(char * tmp_buf, char * table_name, int param_count );
Или даже тупое дублирование backslash (если в параметрах никогда не попадется кавычка):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
// caller must free returned pointer
char * quick_and_dirty_double_backslash (char * src){
  char * dst = malloc(strlen(src) *  2  +  1 );
  size_t pos =  0 ;
  while( *src ) {
    dst[ pos++ ] = *src;
    if ( '\\' == *src )
      dst[ pos++ ] = *src;
    src++;
  }
  dst[pos] =  0 ;
  return dst;
}
накропать за несколько минут тоже лень?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
22.02.2008, 13:49
    #35150425
Garik888
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Пишешь вот так свой путь: 'c:'||E'\\'||'windows'
...
Рейтинг: 0 / 0
22.02.2008, 14:02
    #35150470
pamir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите вставить неформатированный текст
Garik888Пишешь вот так свой путь: 'c:'||E'\\'||'windows'Зачем отвечать на вопрос полутора годичной давности?
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите вставить неформатированный текст / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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