【问题标题】:TinyTDS error when using uniq function in has_many, through在 has_many 中使用 uniq 函数时出现 TinyTDS 错误,通过
【发布时间】:2014-06-26 20:23:39
【问题描述】:

我目前正在跑步:

Windows 7 64-bit
Rails 4.1.1
Ruby 2.0.0p481
tiny_tds [gem] 0.6.2

我已成功启动 Rails 应用程序以访问远程 SQL Server(我不确定服务器的版本是什么)。我有一个模型resource.rb,具有以下关联:

class Resource < ActiveRecord::Base
    self.table_name = 'tResources'
    self.primary_key = 'emp_Id'

    has_many :project_resources, foreign_key: 'emp_Id'
    has_many :projects, through: :project_resources
    ...

    default_scope { order("#{Resource.table_name}.lastname ASC") }
    ...

模型project_resource.rb有以下内容:

class ProjectResource < ActiveRecord::Base
    self.table_name = 'tProject_Resources'
    self.primary_key = 'key_Id'

    belongs_to :project
    belongs_to :resource, foreign_key: 'emp_Id'
    belongs_to :calendar
    ...

这一切都很好。如果我有资源r,我可以通过引用r.projects 来获取与r 关联的所有项目。但是这个关联里有一些重复的项目,所以在我看来,我目前正在成功使用r.projects.uniq

我想将uniq 移动到has_many 如下:

has_many :projects, -> { uniq }, through: :project_resources

以这种方式定义关联后,我尝试过的唯一成功的 r.projects 引用是:r.projects.count,它确实为我提供了资源 r 的唯一项目的准确计数。

但是,其他引用,例如简单的 r.projects,会产生 TinyTDS 错误:

irb(main):010:0> r.projects
  Project Load (290.0ms)  EXEC sp_executesql N'SELECT DISTINCT *, __order FROM (
 SELECT [tProjects].*, DENSE_RANK() OVER (ORDER BY name ASC) AS __order, ROW_NUM
BER() OVER (PARTITION BY [tProjects].* ORDER BY name ASC) AS __joined_row_num FR
OM [tProjects] INNER JOIN [tProject_Resources] ON [tProjects].[project_Id] = [tP
roject_Resources].[project_id] WHERE [tProject_Resources].[emp_Id] = @0 ) AS __s
q WHERE __joined_row_num = 1 ORDER BY __order', N'@0 int', @0 = 471  [["emp_Id",
 471]]
TinyTds::Error: Incorrect syntax near '*'.: EXEC sp_executesql N'SELECT DISTINCT
 *, __order FROM ( SELECT [tProjects].*, DENSE_RANK() OVER (ORDER BY name ASC) A
S __order, ROW_NUMBER() OVER (PARTITION BY [tProjects].* ORDER BY name ASC) AS _
_joined_row_num FROM [tProjects] INNER JOIN [tProject_Resources] ON [tProjects].
[project_Id] = [tProject_Resources].[project_id] WHERE [tProject_Resources].[emp
_Id] = @0 ) AS __sq WHERE __joined_row_num = 1 ORDER BY __order', N'@0 int', @0
= 471
ActiveRecord::StatementInvalid: TinyTds::Error: Incorrect syntax near '*'.: EXEC
 sp_executesql N'SELECT DISTINCT *, __order FROM ( SELECT [tProjects].*, DENSE_R
ANK() OVER (ORDER BY name ASC) AS __order, ROW_NUMBER() OVER (PARTITION BY [tPro
jects].* ORDER BY name ASC) AS __joined_row_num FROM [tProjects] INNER JOIN [tPr
oject_Resources] ON [tProjects].[project_Id] = [tProject_Resources].[project_id]
 WHERE [tProject_Resources].[emp_Id] = @0 ) AS __sq WHERE __joined_row_num = 1 O
RDER BY __order', N'@0 int', @0 = 471

我正在寻找一些关于为什么会发生此错误的指导。谢谢。

【问题讨论】:

    标签: ruby-on-rails sql-server tiny-tds


    【解决方案1】:

    这一行有问题

    PARTITION BY [tProjects].*
    

    我希望这里有一个特定的列。

    我的 PC 上有类似的设置,但无法在 rails 控制台中复制您的问题。 activerecord-sqlserver-adapter (4.1.0)tiny_tds (0.6.2)rails (4.1.1)activerecord (4.1.1, 4.0.3)

    这是我的输出:

    rails c
    Loading development environment (Rails 4.1.1)
    2.1.0 :001 > require 'LvQaOrderService'
     => true
    2.1.0 :002 > p = Product.where(id: 36860201)  
    SQL (282.9ms)  USE [order_service]  
    Product Load (313.2ms)  
    EXEC sp_executesql N'SELECT [products].* FROM [products] WHERE [products].[id] = 36860201'
    2.1.0 :003 > p.first.inventories
    Inventory Load (343.9ms)  
    EXEC sp_executesql N'SELECT DISTINCT [inventory].* FROM [inventory] INNER JOIN [product_inventory] ON [inventory].[id] = [product_inventory].[inventory_id] WHERE [product_inventory].[product_id] = @0', N'@0 bigint', @0 = 36860201`
    

    这是我的设置:

    #product.rb
    class Product < LvQaOrderService
    has_many :product_inventories
    has_many :inventories, -> { uniq }, :through => :product_inventories
    end
    
    #product_inventory.rb
    class ProductInventory < LvQaOrderService
    self.table_name = "product_inventory" 
    
    belongs_to :product
    belongs_to :inventory
    end
    
    #inventory.rb
    class Inventory < LvQaOrderService
    self.table_name = "inventory" 
    
    has_many :product_inventories
    has_many :products, :through => :product_inventories
    end
    

    【讨论】:

    • 问题是我的代码没有直接创建该行。 Rails 和/或 tiny_tds 都可以。所以我想知道在这种情况下 tiny_tds gem 中是否存在错误。
    • 那么activerecord-sqlserver-adapter 的 gem 版本是什么?
    • 我的activerecord-sqlserver-adapter gem 版本是 4.1.0。
    • @luker 我用更多信息更新了我的答案。希望能帮助到你。就我而言,我无法复制它。诡异的。您能否提供有关您的设置的更多信息?
    • 在我最初的问题陈述中,我添加了一些我在模型中使用的信息。这些表对我来说是外部的,所以我不控制它们的关键结构。他们没有使用 Rails 标准命名,所以我明确设置表名和主键,并在需要时使用foreign_key。我还有一个default_scope 资源。模型中存在与其他表格的关联,我认为这些关联不会解决这个问题。如果您想知道其他任何事情,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2015-01-28
    • 2020-08-09
    • 2012-03-04
    • 1970-01-01
    • 2015-09-12
    • 2022-12-11
    相关资源
    最近更新 更多