【问题标题】:Accessing individual column using database link使用数据库链接访问单个列
【发布时间】:2019-01-10 08:30:33
【问题描述】:

我是甲骨文世界的新手。我最近在 Oracle 中创建了一个数据库链接来从 SQL Server 获取数据,并且我能够获取数据。

SELECT * FROM emp@dblink

上述查询从托管在 SQL Server 上的“emp”表中获取所有行。

但是当我引用如下所示的特定列时,Oracle 会抛出错误。

--This query failed
SELECT empid FROM emp@dblink

错误: ORA-00904:“EMPID”:标识符无效

但是当我将 empid 列用双引号括起来时,它就开始工作了。

--This query passed
SELECT "empid" FROM emp@dblink

我想知道为什么在引用单个列而不用双引号括起来时会出错。

【问题讨论】:

  • 可能是区分大小写的问题,从emp中检查empid是大写还是小写,至于双引号具体区分大小写
  • 在emp表中很小。但是,我尝试了小资本和资本都没有运气。我怀疑这可能是由于 SQL Server 驱动程序的一些配置问题,但不知道如何修复它。

标签: sql-server oracle linked-server database-link


【解决方案1】:

在 Oracle 中,数据字典中的列通常不区分大小写:

select empno from EMP
select EMPNO from emp
select EMPNO from Emp

将全部匹配被调用 EMP 的数据字典中名为 EMPNO 的列。如果您想区分大小写,则使用双引号,例如

select "EmpNo" from EMP

只要 EMP 表最初定义为:

create table emp ("EmpNo" int)

等等。 SQL Server 不同,它在字典中保留大小写,因此当我们通过 dblink 从 Oracle 查询它时,我们保留了大小写。因此,SQL Server 中名为 MixedCase 的列必须在 Oracle 中引用为“MixedCase”。

【讨论】:

  • 您好,Emp 表托管在 SQL Server 上,列正是我提到的方式,即 empid
  • Oracle 是区分大小写的 - 它只是默认行为是将未加引号的标识符转换为大写,这会掩盖用户区分大小写的情况。
  • @SumanKumar 正如我所提到的那样:'因此,SQL Server 中名为 MixedCase 的列必须在 Oracle 中引用为“MixedCase”。'
  • @ConnorMcDonald - 有什么方法可以关闭它(以便我可以将 SQL Server 中的 MixedCase 称为 DB 链接中的 MixedCase)?也许通过 Oracle Gateway 配置中的一些排序规则设置?
  • 在 Oracle(或 SQL Server)中按照以下方式创建视图: create view UPPER_CASE_NAME as select * from "sql_server_mixed_case_name";然后参考 UPPER_CASE_NAME
【解决方案2】:

[TL;DR] 最简单的做法是永远不要在对象名称周围使用双引号,而让 oracle 以其默认方式管理区分大小写,如果您正在引用区分大小写的数据库中的列然后通过 dblink 以大写形式命名这些列,这样您就不必在 Oracle 中使用双引号。

默认情况下,Oracle 数据库区分大小写;但是,默认情况下,它们也会将所有内容都转换为大写,以便从您(用户)那里抽象出区分大小写。

CREATE TABLE emp ( empid NUMBER(12,0) );

然后:

SELECT empid FROM emp;
SELECT Empid FROM emp;
SELECT EMPID FROM emp;
SELECT eMpId FROM emp;
SELECT "EMPID" FROM emp;

都会给出相同的输出并且:

SELECT TABLE_NAME, COLUMN_NAME FROM USER_TAB_COLUMNS;

输出:

TABLE_NAME COLUMN_NAME
---------- -----------
EMP        EMPID

(注意表名是大写的)。

如果您使用双引号,那么 oracle 将尊重您在对象标识符中使用大小写:

CREATE TABLE emp ( "empid" NUMBER(12,0) );

然后:

SELECT TABLE_NAME, COLUMN_NAME FROM USER_TAB_COLUMNS;

输出:

TABLE_NAME COLUMN_NAME
---------- -----------
EMP        empid

(注意:Oracle 尊重empid 列的区分大小写)。

您现在只能使用以下方法引用该列:

SELECT "empid" FROM emp;

这些查询将失败:

SELECT empid FROM emp;
SELECT Empid FROM emp;
SELECT EMPID FROM emp;
SELECT eMpId FROM emp;
SELECT "EMPID" FROM emp;

由于 Oracle 会将标识符转换为大写,并且没有 EMPID 列,只有 empid 列。

使用双引号引用列或将列重命名为 EMPID 以允许您利用 Oracle 的默认行为,即从用户那里抽象出区分大小写(但这可能会破坏其他使用双引号的查询在非大写的列名上)。

【讨论】:

  • 您好,Emp 表托管在 SQL Server 上,但不在 Oracle 上,我正在尝试使用 DBLinks 访问它。 SQL Server 中的列名正是我在查询中提到的方式,即empid。
  • @SumanKumar 同样适用 - Oracle 区分大小写,但其默认行为是将所有标识符转换为大写。因此,当您执行SELECT empid FROM emp@dblink 时,Oracle 会将其解析为SELECT EMPID FROM emp@dblink,当查询到达 SQL Server 时,查询将失败,这也是区分大小写的,并且该列的大小写不同。使用双引号告诉 Oracle 尊重名称的大小写敏感性,而不是将标识符转换为大写或将 SQL Server 中的列重命名为 EMPID(大写),您应该能够使用不带引号的标识符。
  • SQL Server 默认不区分大小写,即无论是 empid、EmpID 还是 EMPID 对于 SQL Server 来说都是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 2023-02-14
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
相关资源
最近更新 更多