【问题标题】:When I imported a tinyint column from SQL Server to Oracle 10g, why did I get negative values?当我将一个 tinyint 列从 SQL Server 导入到 Oracle 10g 时,为什么会得到负值?
【发布时间】:2013-05-31 19:02:53
【问题描述】:
我最近遇到了一个问题,我们正在运行一个数据迁移脚本,通过 Oracle DBLink 将数据从 SQL Server 移动到 Oracle 10g。一切正常,直到我们在生产 Oracle 环境中运行脚本。对于在 SQL Server 中定义为 tinyint 的某些列,我们发现 SQL Server 数据库中高于 127 的值现在是负值(比原始值少 256)。为什么脚本在开发和测试数据库中有效,但在生产环境中无效?
【问题讨论】:
标签:
sql-server
character-encoding
oracle10g
dblink
【解决方案1】:
我提出并回答我自己的问题是因为 Google 和 StackOverflow 无法帮助我解决这个问题,至少在我使用的搜索词方面是这样。在我们开始研究时,我们发现 SQL Server 将 tinyint 视为无符号字节(0 到 255),而 Oracle 将其视为有符号字节(-128 到 127)。但是我们正在导入 NUMBER(3) 列,这是合适的。编写数据迁移脚本的人出于某种原因需要使用 Oracle 的 to_number 函数来读取 SQL Server tinyint 列。因此,如果您在我们的开发和测试环境中运行此查询,它会在第二列中返回一些奇怪的字符,但在我们的生产环境中,它在两列中返回相同的负数。
SELECT to_number("SomeTinyIntColumn"), "SomeTinyIntColumn"
FROM MySQLServerDBLink@mydomain.com
我们最终发现它在开发和测试环境中工作的原因是因为那里的字符集是 UTF-8,但在生产中它是西欧 8 位字符集:
SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET';
-- Dev and Test: AL32UTF8
-- Prod: WE8ISO8859P1
因此,似乎通过 DBLink 将 SQL Server tinyint 列作为单个 UTF-8 字符读取并将其转换为 Oracle NUMBER(3) 列是可行的,前提是您为 Oracle 数据库使用 UTF-8 字符集。如果 DBLink 自己处理了转换(使 to_number 转换变得不必要),那就太好了,但它似乎真的不知道如何处理 SQL Server tinyint强>。
我希望有一天这对其他人有所帮助!