php - 经验丰富的新手的 Oracle 陷阱

标签 php mysql sql-server oracle postgresql

一般来说,对于刚接触该平台但不熟悉关系数据库(MySQL、MS SQL Server、Postgres 等)的人来说,Oracle 有哪些陷阱。

我正在寻找的东西的两个例子

  1. 许多关系数据库产品都会为您处理创建 auto_increment 键。 Oracle没有,必须手动创建sequence,然后创建trigger

  2. 通过SQL Developer接口(interface)插入数据时,需要手动提交数据

PHP 相关陷阱的奖励积分,因为这是我将这个假设的经验丰富的新手将使用的平台。

最佳答案

注意:我在这里只解释陷阱,我。 e. Oracle 的行为与其他系统不同的情况。 Oracle 与其他 RDBMS 相比有很多优势,但它们不是本文的主题。

  • 没有 FROM 就不能SELECT

    SELECT  1
    

    会失败,你需要:

    SELECT  1
    FROM    dual
    
  • 空字符串和NULL是一回事。

    SELECT  *
    FROM    dual
    WHERE   '' = ''
    

    不返回任何内容。

  • 既没有TOP也没有LIMIT。您在 WHERE 子句中限制结果:

    SELECT  *
    FROM    (
            SELECT  *
            FROM    mytable
            ORDER BY
                    col
            )
    WHERE   rownum < 10
    

    正是这样,使用子查询,因为 ROWNUMORDER BY 之前计算。

  • 相关子查询的嵌套深度不能超过一层。这个会失败:

    SELECT  (
            SELECT  *
            FROM    (
                    SELECT  dummy
                    FROM    dual di
                    WHERE   di.dummy = do.dummy
                    ORDER BY
                            dummy
                    )
            WHERE   rownum = 1
            )
    FROM    dual do
    

    这是个问题。

  • NULL 值未编入索引。此查询将不使用索引进行排序:

    SELECT  *
    FROM    (
            SELECT  *
            FROM    mytable
            ORDER BY
                    col
            )
    WHERE   rownum < 10
    

    ,除非 col 被标记为 NOT NULL

    请注意,NULL 不是 未编入索引。您可以在可为 null 的列上创建索引,非 NULL 值将进入索引。

    但是,当查询条件假定NULL 值可能满足时,将不会使用索引。

    在上面的示例中,您希望返回所有值(包括 NULL)。然后索引不知道非 NULL 值,因此无法检索它们。

    SELECT  *
    FROM    (
            SELECT  *
            FROM    mytable
            ORDER BY
                    col
            )
    WHERE   rownum < 10
    

    但是这个查询将使用索引:

    SELECT  *
    FROM    (
            SELECT  *
            FROM    mytable
            WHERE   col IS NOT NULL
            ORDER BY
                    col
            )
    WHERE   rownum < 10
    

    ,因为非NULL 值永远无法满足条件。

  • 默认情况下,NULL 排在最后,而不是排在前面(就像在 PostgreSQL 中,但不同于 MySQL SQL Server)

    这个查询:

    SELECT  *
    FROM    (
            SELECT  1 AS id
            FROM    dual
            UNION ALL
            SELECT  NULL AS id
            FROM    dual
            ) q
    ORDER BY
            id
    

    会回来

    id
    ---
    1
    NULL
    

    要像在 SQL ServerMySQL 中那样排序,请使用:

    SELECT  *
    FROM    (
            SELECT  1 AS id
            FROM    dual
            UNION ALL
            SELECT  NULL AS id
            FROM    dual
            ) q
    ORDER BY
            id NULLS FIRST
    

    请注意,它会破坏 rownum 顺序,除非后者未在子查询之外使用(如上文所述)

  • "MYTABLE""mytable"(双引号很重要)是不同的对象。

    SELECT  *
    FROM    mytable -- wihout quotes
    

    将从前者中选择,而不是后者。如果前者不存在,则查询失败。

    CREATE TABLE mytable
    

    创建 "MYTABLE",而不是 "mytable"

  • Oracle 中,所有隐式锁(由 DML 操作产生)都是行级的,永远不会升级。即没有不受事务影响的行可以被隐式锁定。

    作者永远不会阻止读者(反之亦然)。

    要锁定整个表,您应该发出显式的 LOCK TABLE 语句。

    行锁存储在数据页上。

  • Oracle中,没有“CLUSTERED索引”,只有“索引组织表”。默认情况下,表是堆组织的(不同于 SQL ServerMySQL with InnoDB)。

    Oracle 世界中,“集群存储”意味着组织多个表,以便共享公共(public)键(来自多个表)的行也共享一个数据页。

    单个数据页托管来自多个表的多行,这使得对该键的连接非常快。

关于php - 经验丰富的新手的 Oracle 陷阱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1209039/

相关文章:

sql - SQL Server 中的 BETWEEN

mysql - SQL条件语句中如何处理null?

mysql - 在mysql中对一个简单的follower表进行分区

javascript - 我正在进行 JavaScript 验证,但当我输入姓氏时它无法正常工作,它不会显示错误并提交表单

php - 通过 php 检查和更新 mysql 表

php - 将数组与数据库进行比较

c# - 如何转换十进制?将 LINQ 与存储过程结合使用时转换为十进制

sql-server - 计算SQL中两个日期之间出现了多少个月 'January'

php - Apache2/phpmyadmin - PHP 不工作

php - 通过 jQuery 确认 2 个密码字段