#sqlite #try-catch #tcl
#sqlite #попробуйте-catch #tcl
Вопрос:
Урезанный, что я пытаюсь сделать, это следующее
set selectQuery "SELECT col1, col2 FROM tableName"
db1 eval $selectQuery {
set insertQuery "INSERT INTO tableName VALUES($col1, $col2)"
db2 eval $insertQuery {
# Do trivial stuff to show progress
}
}
который в основном копирует содержимое db1.tableName в db2.tableName.
Проблема в том, что в моем случае большая часть содержимого db1.tableName уже существует в db2.tableName. Итак, в принципе, я просто хочу скопировать то, что еще не существует, поэтому я подумал, что просто вставлю все и позволю вставкам завершиться неудачно, когда данные уже есть. Это не работает, потому что весь скрипт останавливается, как только одна вставка завершается неудачей. Я пытался использовать catch, чтобы проигнорировать сбой и разрешить сценарию продолжить, но у меня не получилось. Есть идеи?
Кроме того, может быть лучший способ скопировать содержимое db1.tableName в db2.tableName без копирования того, что там уже есть… Любая помощь будет оценена!
Шон
P.S Если у вас есть идеи для лучшего названия, это также было бы полезно..
Комментарии:
1. Не можете ли вы просто
[catch]
выполнить оценку команды вставки? Смотрите wiki.tcl.tk/catch2. Пожалуйста, заключите ваш SQL в {фигурные скобки}. Это позволяет SQLite автоматически использовать подготовленные инструкции, что повышает как безопасность, так и скорость.
3. @Donal Fellows: Спасибо, мне действительно нужна скорость в этом конкретном случае, поэтому я попробую!
4. @Donal Fellows: Я только что прочитал, что использование фигурных скобок не приведет к замене. Мне нужна замена, поэтому, я думаю, я должен придерживаться кавычек?
Ответ №1:
В Sqlite есть конструкция INSERT ИЛИ REPLACE INTO, которая может быть полезна в этом случае.
Ответ №2:
Хотя я не знаком с вашими командами API базы данных, поэтому я не могу прокомментировать, как вы просматриваете результаты запроса, но я могу предложить несколько вещей.
Сначала попробуйте перехватить еще раз. Я всегда нахожу такое использование немного странным, но в конце концов вы к нему привыкаете. Вот пример:
if { [catch { db2 eval $insertQuery} errmsg] } {
#There was an error - it is stored in $errmsg"
} else {
#success! Congratulations.
}
В вашем случае, я полагаю, вы просто хотите игнорировать любые ошибки вставки, поэтому вы можете просто сделать:
set selectQuery "SELECT col1, col2 FROM tableName"
db1 eval $selectQuery {
set insertQuery "INSERT INTO tableName VALUES($col1, $col2)"
if { ![catch { db2 eval $insertQuery} errmsg] } {
# Do trivial stuff to show progress
}
}
Вы также могли бы попробовать сначала выполнить запрос и поместить результаты запроса в список TCL (или список списков) — затем выполните foreach в списке, выполнив вставки. Иногда базы данных могут быть забавными по поводу изменения данных, хотя в вашем случае это совсем не похоже на то, что происходит.
Комментарии:
1. SQL должен быть в {фигурных скобках}, а не в «кавычках», чтобы избежать неприятных цитат SQL. Избавьте себя от лишних хлопот и сделайте это прямо сейчас. 🙂