如何从以正确列类型传递的 SQL 服务器获取数据

Posted

技术标签:

【中文标题】如何从以正确列类型传递的 SQL 服务器获取数据【英文标题】:How can I get data from a SQL server passed with correct column type 【发布时间】:2018-01-19 18:34:49 【问题描述】:

我正在从 SQL 服务器读取数据。 SQL Server 数据库有表格,其中包含来自各种来源(医疗中心、HMO 和州登记处)的个人特定信息。每个表中都有一个名为 PID 的参与者标识符。 PID的构建很大程度上取决于数据源,有些数据源的PID值完全由数字组成,而另一些数据源的PID值则是混合字母数字。

为了生成组合来源分析,我需要构建一个由来自各种来源的表格组成的数据框。 PID 作为 str(20) 存储在 SQL 服务器上。我想将数据读入 R,保持 SQL 服务器上指定的类型。我正在使用带有 odbcConnect 的 RODBC 包来声明我与 SQL 服务器的 ODBC 连接和 sqlFetch 来读取数据,如下所示:

> library("RODBC")
> ch <- odbcConnect("PROSPRdfm", uid="........", pwd="........")
> 
> # Read h3_crc_ppt data from SQL server
> crc_ppt <- sqlFetch(ch, "h3_crc_ppt")

然后我附上 crc_ppt 并测试 PID 是否为字符:

> attach(crc_ppt)
> is.character(PID)
[1] FALSE

对于这个特定的表,所有 PID 都是数字。但其他表具有字母数字的 PID。是否有可以传递给 sqlFetch 的参数来强制 R 遵守 SQL 服务器上指定的变量类型?

【问题讨论】:

尝试str(crc_ppt) 看看您的查询返回什么。它可能是一个 data.frame。 是的,crc_ppt 是 data.frame 类型。这就是为什么我在查询列 PID 是否为字符之前附加 crc_ppt。 【参考方案1】:

试试sqlFetch(ch, "h3_crc_ppt", as.is = TRUE)

来自?sqlQuerysqlFetchwraps)

在可能的情况下,sqlGetResults 以二进制形式传输数据:这发生在 (ODBC) SQL 类型 double、real、integer 和 smallint 的列以及二进制 SQL 类型(作为原始向量列表传输,给定类“ODBC_binary” )。所有其他 SQL 数据类型都由 ODBC 接口转换为字符串。

本段仅适用于 ODBC 作为字符向量返回的 SQL 数据类型。如果在创建连接时(请参阅 odbcConnect)DBMSencoding 设置为非空值,则重新编码字符串。然后,如果 as.is 对一列为真,则将其作为字符向量返回。否则(如果检测到)日期、日期时间和时间戳值将转换为“日期”或“POSIXct”类。 (一些驱动程序似乎将时间与日期混淆,因此时间也可能会被转换。此外,一些 DBMS(例如 Oracle 的)日期概念是日期时间。)其余情况由 R 使用 type.convert 转换。当字符数据要转换为数字数据时,options("dec") 的设置用于映射 ODBC 驱动程序在设置小数点时使用的字符——当 RODBC 初始化时,这将设置为特定于语言环境的值,如果它尚未设置。

【讨论】:

当我添加 as.is = TRUE 时,每一列都作为字符返回。这似乎不是答案。 您的答案在于文档。 “那么如果 as.is 对一列为真,则它作为字符向量返回。”根据您的 PID 列的索引制作as.is = c(FALSE, FALSE, ...TRUE) 好的,这行得通。但请原谅我说这是非常糟糕的行为。我只是在熟悉 R,试图从 SAS 转移。该数据库有许多表,有些表有数百个变量。有更多的变量,其表示应该是字符,而不仅仅是提到的一个变量。 (PID 是关系 DBMS 中的关键变量。)SAS 处理读取表并接受 SQL 服务器上指定的类型。必须手动构造一个冗长的逻辑向量对于不正确的规范来说已经成熟了。 我不明白。问题不只是 PID 是数字和字母数字字符的混合吗?只有 PID 列需要为as.is = TRUE,其余的可以为假,这应该是使用rep 构造的简单逻辑。根据我的理解,文档建议即使在 as.is = FALSE 时,也应在 R 中将 SQL 字符串作为字符串读取,因此可能还有其他问题。 没有。我只介绍了 PID 作为字符,因为它是 RDBMS 中的一个关键变量并说明我的问题。还有许多其他 ID 变量是其他表的关键变量。还有 ZIP 和 FIPS 代码以及其他应该是字符的变量。 R 想要将所有字符串转换为因子。这确实减慢了数据处理速度。必须逐个位置指定应该使用 as.is=TRUE 读取哪些列真的很乏味。对于 R 不遵守 SQL DB 类型规范,我想不出任何理由。

以上是关于如何从以正确列类型传递的 SQL 服务器获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PL-SQL 在 Oracle 中获取列数据类型

Azure 数据工厂 - Azure SQL 托管服务不正确的输出列类型

如何在 Sybase 中获取正确的列类型

如何在 Spark SQL 中获取列的数据类型?

如何使用 dateTimePicker 将日期插入 SQL 数据库日期列?

SQL 服务器查询以获取表中的列列表以及数据类型、NOT NULL 和 PRIMARY KEY 约束