我正在编写一个ORM(对象关系模型),并且我在此错误消息上停留了一段时间。我确实将其范围缩小到了update和save方法(我感觉该错误最有可能是在update方法中),但是我无法弄清楚语法错误的发生位置。
这是错误消息:
SQLite3::SQLException: near ".": syntax error
from /Users/karenlee/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:147:in `initialize'
这是我的ORM:
require_relative 'questions_database'
class User
attr_reader :id
attr_accessor :fname, :lname
# displays all users
def self.all
users = QuestionsDatabase.instance.execute("SELECT * FROM users")
users.map { | user_info | User.new(user_info) }
end
# finds a user by their primary id
def self.find_by_id(id)
found_user = QuestionsDatabase.instance.execute(<<-SQL, id: id)
SELECT
users.*
FROM
users
WHERE
users.id = :id
SQL
found_user.nil? ? nil : User.new(found_user.first)
end
# finds a user by their first and last name
def self.find_by_name(fname, lname)
name = {fname: fname, lname: lname}
found_user = QuestionsDatabase.instance.execute(<<-SQL, name)
SELECT
users.*
FROM
users
WHERE
users.fname = :fname AND users.lname = :lname
SQL
found_user.nil? ? nil : User.new(found_user.first)
end
# creates a new user instance
def initialize(options)
@id, @fname, @lname = options.values_at('id', 'fname', 'lname')
end
# saves the user into the database (or updates when needed)
def save
if self.id
update
else
create
end
end
private
# helper method to update the database
def update
values = {id: id, fname: fname, lname: lname}
QuestionsDatabase.instance.execute(<<-SQL, values)
UPDATE
users
SET
users.fname = :fname, users.lname = :lname
WHERE
users.id = :id
SQL
end
# helper method to create a row in the database
def create
name = {fname: fname, lname: lname}
QuestionsDatabase.instance.execute(<<-SQL, name)
INSERT INTO
users (fname, lname)
VALUES
(:fname, :lname)
SQL
self.id = QuestionsDatabase.instance.last_insert_row_id
end
end
如果需要,这里是QuestionsDatabase类:
require 'sqlite3'
require 'singleton'
class QuestionsDatabase < SQLite3::Database
include Singleton
def initialize
super('questions.db')
self.type_translation = true
self.results_as_hash = true
end
end
更新:
我找到了我的错误所在!原来,我应该只说fname = :fname, lname = :lname
而不是说users.fname = :fname, users.lname = :lname
。但是我仍然不确定为什么会这样。当我不使用别名时,更新语句似乎不喜欢它,但是对此做更多的解释会很好!
答案 0 :(得分:1)
事实证明,别名仅在FROM子句中可用。因此,如果我要在UPDATE语句中使用别名,则必须采用不同的结构。我必须使用FROM子句。请参阅此链接以获取有关重组的更多信息!
https://sqlstudies.com/2013/09/16/dba-myths-you-cant-use-an-alias-in-an-update-statement/
答案 1 :(得分:1)
原来,我应该只是说fname =:fname,lname =:lname而不是说users.fname =:fname,users.lname =:lname。但是我仍然不确定这是为什么。
如果您查看UPDATE
syntax diagrams,则会看到它只是使用简单的列名。无需指定表名,因为您一次只能更新一个表。像SELECT
一样,没有歧义的余地。因此,解析器规则在那里不支持可选的表名组件。