首页 > 解决方案 > 带有 in_schema 的 tbl 返回“无效的对象名称”错误

问题描述

连接到 SQL 服务器后,可以列出其中的数据库。

con = dbConnect(odbc(),
             Driver   = "ODBC Driver 17 for SQL Server",
             Server   = "xxxxxxxxxxxx",
             UID = "xxxxxxxxxxxx",
             PWD = "xxxxxxxxxxxx",
             Port     = xxxxxxxxxxxx)

在这里您可以找到成功的连接。

在此处输入图像描述

之后,我只想列出此 SQL 服务器中的数据库

databases = dbGetQuery(con, "SELECT name FROM master..sysdatabases")

在此处输入图像描述

由于我对 SQL 不熟悉,所以看到“con”中有一个已经分配的数据库“DB01CWE5462”对我来说有点奇怪。该数据库也可以在 dbGetQuery (DB01CWE5462) 的结果中找到。我猜这个数据库是自动分配给con的。

但是,我想导出上面看到的黄色突出显示的表格。下面的代码之前(一个月前)是成功的,但现在它返回一个错误。

tbl(con, in_schema("DB01WEA84103.dbo","Ad10Min1_Average"))

错误:nanodbc/nanodbc.cpp:1655:42000:[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]无效的对象名称“DB01WEA84103.dbo.Ad10Min1_Average”。[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]无法准备语句。'SELECT * FROM "DB01WEA84103.dbo"."Ad10Min1_Average" AS "q13" WHERE (0 = 1)'

经过一番搜索,我找到了一个与上述代码之前成功运行相比相当慢的解决方案。

dbReadTable(con, 'Ad10Min1_Average', schema='DB01WEA84103.dbo')

那么,我错过了什么?对于产生错误的 con 和 in_schema 代码,我应该怎么做才能再次工作?

标签: rsql-serverodbcdatabase-schemadbplyr

解决方案


速度上的差异是因为tbl(con, ...)正在创建远程表的访问点,而dbReadTable(con, ...)正在将表从 SQL 读取/复制到 R 中。

您使用的方法是指定数据库和模式的标准解决方法。我猜想 dbplyr 包已经更新,这意味着这个解决方法现在需要一个额外的步骤。

仔细查看错误消息中的 SQL 会发现原因:

SELECT * FROM "DB01WEA84103.dbo"."Ad10Min1_Average"

注意 . 周围的双引号"DB01WEA84103.dbo"。双引号告诉 SQL 将其视为单个对象:具有 name 的模式DB01WEA84103.dbo,而不是两个对象:具有 name 的数据库和具有 nameDB01WEA84103的模式dbo

理想情况下,此查询将显示为:

SELECT * FROM "DB01WEA84103"."dbo"."Ad10Min1_Average"

现在双引号中不包含句号。

阅读 dbplyr 文档(链接in_schema指定模式和表的名称“......将被自动引用;用于sql()传递不会被引用的原始名称。”

因此,我建议您尝试:

tbl(con, in_schema(sql("DB01WEA84103.dbo"),"Ad10Min1_Average"))

笔记:

  • SQL 中的双引号用于表示单个对象,忽略特殊字符。方括号在 SQL 中经常用于相同的目的。
  • 在 R 中使用单引号还是双引号并不影响 SQL 代码是否包含双引号。这是由 dbplyr 的翻译方法控制的。
  • 如果您的数据库名称包含特殊字符,请尝试将它们括在方括号中:例如[my!odd@database#name].[my%unusual&schema*name].

推荐阅读