Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby SQLite插入的转义字符串_Ruby_Sqlite_Sqlite3 Ruby - Fatal编程技术网

Ruby SQLite插入的转义字符串

Ruby SQLite插入的转义字符串,ruby,sqlite,sqlite3-ruby,Ruby,Sqlite,Sqlite3 Ruby,我正在创建一个Ruby脚本,将一个大约150k行的以制表符分隔的文本文件导入SQLite。到目前为止: require 'sqlite3' file = File.new("/Users/michael/catalog.txt") string = [] # Escape single quotes, remove newline, split on tabs, # wrap each item in quotes, and join with commas def prepare_for

我正在创建一个Ruby脚本,将一个大约150k行的以制表符分隔的文本文件导入SQLite。到目前为止:

require 'sqlite3'

file = File.new("/Users/michael/catalog.txt")
string = []

# Escape single quotes, remove newline, split on tabs, 
# wrap each item in quotes, and join with commas
def prepare_for_insert(s)
  s.gsub(/'/,"\\\\'").chomp.split(/\t/).map {|str| "'#{str}'"}.join(", ")
end

file.each_line do |line|
  string << prepare_for_insert(line)
end

database = SQLite3::Database.new("/Users/michael/catalog.db")

# Insert each string into the database
string.each do |str|
  database.execute( "INSERT INTO CATALOG VALUES (#{str})")
end
在15号线上出错了。如果我用
放置字符串[14]
检查该行,我可以看到它在“s”附近显示错误的位置。它看起来是这样的:
“触摸世界之巅:盲人爬得比眼睛能看到的更远的旅程”


看起来单引号被转义了,那么为什么我仍然得到错误?

不要这样做,字符串插值和SQL往往是一个糟糕的组合。使用准备好的语句,让驱动程序处理引用和转义:

# Ditch the gsub in prepare_for_insert and...
db  = SQLite3::Database.new('/Users/michael/catalog.db')
ins = db.prepare('insert into catalog (column_name) values (?)')
string.each { |s| ins.execute(s) }
当然,你应该用真实的列名替换
column\u name
;您不必在INSERT中指定列名,但无论如何都应该这样做。如果需要插入更多列,请向ins添加更多占位符和参数。执行

使用and应该更快、更安全、更容易,而且不会让您觉得自己是在1999年编写PHP的


此外,您还应该使用来解析标签分隔的文件,XSV格式处理起来并没有多大乐趣(事实上它们是彻头彻尾的邪恶),而且您有更好的时间来处理它们的无意义和边缘情况等等。

Perfect。现在可以了。共有34列。所以,看起来很傻,
(?我还将合并CSV解析器。@michaelmichael:是的,还有34个参数到
ins.execute
中,但是你可以将这些参数放在数组中,并将它们保存在
ins.execute(*array)
中,以检查是否有问题。您还可以使用
(['?']*34)构建占位符。join(',')
(这没关系,因为您确切地知道正在使用什么字符串,但尝试在SQL中使用未知字符串只是自找麻烦)。
# Ditch the gsub in prepare_for_insert and...
db  = SQLite3::Database.new('/Users/michael/catalog.db')
ins = db.prepare('insert into catalog (column_name) values (?)')
string.each { |s| ins.execute(s) }