【问题标题】:Why do SQL joins fail in Oracle?为什么 SQL 连接在 Oracle 中失败?
【发布时间】:2014-05-07 21:24:32
【问题描述】:

我只是尝试 simple 使用 oracle db 与 C# 连接。应该没什么大不了的。但它总是失败。它适用于 MS-Access。问题出在哪里 ? (OleDb 或 Odbc 在这里没有区别,我都试过了)

编辑:

  • 可能是 Oracle 版本的问题吗? (似乎我们使用的是 8.1.7.0.0 和 8.1.5.0.0 模块)

代码:

using System;
using System.Data.Odbc;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string n = Environment.NewLine + "--------------------------------" + Environment.NewLine + Environment.NewLine;

            // connect
            string connectionString = "dsn=TEST;uid=read;pwd=myPwd";
            OdbcConnection connection = new OdbcConnection(connectionString);
            connection.Open();

            // select (key is actually text not numeral)
            string query = "select * from INFOR.ZEITEN where (KEY = 0)";
            query = "select a.KEY, b.GREG from INFOR.ZEITEN a inner join INFOR.ZEITEN b on (a.AUSWEIS = b.AUSWEIS) where (a.KEY like '1')";

            try
            {
                query = query.Replace(Environment.NewLine, " ");
                Console.WriteLine(n + query);
                OdbcCommand command = new OdbcCommand(query, connection);
                OdbcDataReader reader = command.ExecuteReader(); // throws exception
                if (reader != null)
                    Console.WriteLine(n + "success, now read with reader!");
            }
            catch (Exception e)
            {
                Console.WriteLine(n + e.Message + n + e.StackTrace);
            }

            // wait
            Console.ReadKey();
        }
    }
}

输出:

然后是成功的简单选择:

【问题讨论】:

  • 这似乎与 C# 无关。如果两条 SQL 语句之一失败,则应检查它是否有效。您是否尝试过使用查询工具执行该语句?
  • @PanagiotisKanavos 是的,我知道。当我问为什么它在 oracle 中失败时,你告诉那些在我的 Q 上发火的 SO 用户!他们想看 C# 代码。
  • 您使用的是什么驱动程序版本,您连接的数据库版本是什么?其中一个可能太旧而无法支持join 语法。这似乎不太可能,但我们似乎仍然收到有关 8i 的问题,所以谁知道呢。 (你仍然可以在 Pro*C 中设置dbms=v8 也有这个效果)。
  • @AlexPoole 8.1.7.0.0 阅读我上面的编辑。
  • @mini-me - 那么这就是你的问题 *8-) 正如 Joe 所说,Oracle 直到 9i 才支持 ANSI 连接。您将不得不使用带有逗号分隔的表列表和where 子句中的所有连接条件的旧语法。当然,或者您可以迁移到受支持的版本...

标签: sql database oracle join


【解决方案1】:

单词key 是保留字。这意味着它是一个非常糟糕的身份选择。您需要用双引号对其进行转义。这可能有效:

        query = "select a.\"KEY\", b.GREG
                 from INFOR.ZEITEN a inner join
                      INFOR.ZEITEN b
                      on (a.AUSWEIS = b.AUSWEIS)
                 where (a.\"KEY\" like '1')";

我猜\" 会在这种情况下工作,但可能有另一种方法可以插入这个字符。

【讨论】:

  • 喜欢 '1' 是否有效?
  • 如果是这样,第二个语句不应该也失败吗?
  • @JeffRosenberg 。 . .他们都应该失败。 KEY 真的是 SQL 中的保留字。这很奇怪。这是一个简单的例子:sqlfiddle.com/#!4/6010c/3.
  • @HamletHakobyan 。 . .我想我学到了一些东西。尽管如此,对标识符使用保留字还是个坏主意。
  • key是关键字,但不是Oracle中的保留字:docs.oracle.com/cd/B10501_01/appdev.920/a42525/apb.htm
【解决方案2】:

我认为KEY 是数字,那么您不能使用LIKE。这是因为WHERE KEY = 0 工作正常。

【讨论】:

  • KEY 是文本。我自己创建了该表用于测试和调试。
【解决方案3】:

ANSI 连接(例如inner join)首先在 9i 中得到支持。您将需要使用旧语法:

select a.KEY, b.GREG 
 from INFOR.ZEITEN a,
      INFOR.ZEITEN b 
where (a.AUSWEIS = b.AUSWEIS) 
      and  (a.KEY like '1')

请注意,like 运算符在这种情况下等同于 =,但您可能知道

【讨论】:

  • 这似乎是对的。当我按照您的建议更改语法时,我的连接查询在工作之前失败了。我可以使用旧语法的各种连接吗?还是有一些限制?
  • (+) 支持左/右外连接,但不支持完全外连接。以下是一些信息:asktom.oracle.com/pls/asktom/…
【解决方案4】:

什么是错误?您能否编辑您的问题并添加系统向您抛出的实际错误? 首先,我个人建议使用 ODP .NET(Oracle Data provider for .NET)。您可以下载 Oracle 12c here 的最新版本。或者查找您需要的版本。 ODBC 是一个用 C 语言编写的非常古老的驱动程序,使用本地 Windows RPC 技术工作。 要获得完整的 .NET 支持,最好使用 ODP .NET。 其次,检查您是否对导致 sql 失败的表有任何约束。

【讨论】:

  • 这并不能真正回答问题;大多数(如果不是全部)应该是评论。
  • @AlexPoole 我认为这是一个答案。据我了解,可以选择使用额外的包来帮助我避免我遇到的版本问题......?实际上我不愿意使用额外的包/驱动程序。这增加了更多的依赖。因为我有解决选项来使用旧语法。
猜你喜欢
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 2012-05-11
相关资源
最近更新 更多