Мне нужно вставить фрейм данных в базу данных SQL. Я создал сценарий (с использованием циклов, str_c, RODBC) для преобразования моего фрейма данных в команду SQL Insert, но я столкнулся с проблемой с одним "'" нарушением SQL.
Вот пример проблемы:
Фрейм данных выглядит так:
pk b
1 o'keefe
Желаемый результат SQL: INSERT INTO table (pk, b) (1, 'o\'keefe')
gsub("'", "\'", str_replace_na(df$b[1], ""))
[1] "o'keefe"
gsub("'", "\\\\'", str_replace_na(df$b[1], ""))
[1] "o\\'keefe"
Я пробовал str_replace
, str_replace_all
, gsub с fixed = TRUE
и perl = TRUE
и получил тот же результат.
Мне известно о комментарии к Как поставить обратную косую черту в качестве замены в R-строке replace, в котором говорится, что cat()
показывает косую черту. Но это не распространяется на мой фрейм данных или SQL-запрос.
Любая помощь по этой проблеме будет принята с благодарностью!
Дополнительное примечание: я знаю, что R печатает двойную обратную косую черту, как указано в http://r.789695.n4.nabble.com/gsub-replacing-double-backslashes-with-single-backslash-td4453328.html и R: Как заменить пробел ('') в строке * одинарной * обратной косой чертой и пробелом ('\'), хотя на самом деле существует только одна косая черта. Однако мой оператор SQL по-прежнему не будет работать, если присутствуют ноль или две обратные косые черты.
К сожалению, я не использую стандартный SQL, я использую SQL FileMaker Pro, который требует одинарной кавычки. (См. fmhelp.filemaker.com/docs/13/en/fm13_sql_reference.pdf, стр. 18).
Попробуйте поставить одинарную кавычку внутри [']
.
x <- "o'keefe"
y <- gsub("[']", "\\\\'", s)
y
#[1] "o\\'keefe"
Кажется, это добавило к строке два символа, но нет, \
всего один.
nchar(x)
#[1] 7
nchar(y)
#[1] 8
Вы получите тот же результат без квадратных скобок. nchar(gsub("'", "\\\\'", df$b[1]))
также является 8
.
Итак, я думаю, что вы поняли, что второй результат OP (показывающий 2 \ вместо одного) на самом деле может быть в порядке и работать в SQL. Но в добавленных скобках нет необходимости. В этом случае достаточно выполнить gsub("'", "\\\\'", df$b[1])
.
@prosoitos Вы правы, скобки нужны только с метасимволами (и fixed = FALSE
, R по умолчанию).
Я не использую SQL, поэтому я не мог проверить, действительно ли double \ был только одним, но в дополнение к вашему умному тесту nchar()
я попытался запустить "\U005C"
, и он действительно дает [1] "\\"
(тогда как, например, "\U002F"
дай [1] "/"
) :) Так что ты однозначно прав в этом :). Итак, ответ заключается в том, что OP уже нашел решение своей второй попыткой (за исключением того, что str_replace_na()
был ненужным).
Но мне неприятно публиковать это в качестве ответа, потому что вы заслуживаете похвалы за понимание, что \\ был только одним \ (даже если ваша скобка добавила шума к ответу).
@prosoitos Если выложишь, я удалю свой.
Спасибо @Rui Barradas. Я выложил это. Но удалять свой не обязательно.
Фактически, "o\\'keefe"
- это то, что вам нужно: двойная черная косая черта на самом деле представляет собой одинарную обратную косую черту.
Например:
\ U005C - это символ Юникода для обратной косой черты. Пока что:
"\U005C"
[1] "\\"
В то время как \ U002F - это символ Юникода для косой черты и:
"\U002F"
[1] "/"
Итак, ваше второе решение уже дало вам то, что вы хотите. Удаление ненужного str_replace_na()
:
gsub("'", "\\\\'", df$b[1])
[1] "o\\'keefe"
Примечание: на самом деле заслуга @Rui Barradas, который показал, что двойная обратная косая черта представляет собой одиночную обратную косую черту с:
nchar("\\")
[1] 1
Стандартный SQL требует, чтобы вы удвоили одинарные кавычки внутри одинарных кавычек. Обратная косая черта в стиле C не является частью стандартного SQL (хотя возможно, что база данных, которую вы используете, но не упомянула, поддерживает ее как расширение стандартного SQL).