“ {SQLite3 :: SQLException:near“。”:语法错误“是什么意思?

时间:2019-12-02 00:21:35

标签: sql

我正在编写一个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。但是我仍然不确定为什么会这样。当我不使用别名时,更新语句似乎不喜欢它,但是对此做更多的解释会很好!

2 个答案:

答案 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一样,没有歧义的余地。因此,解析器规则在那里不支持可选的表名组件。