AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 274063
Accepted
ellie-lumen
ellie-lumen
Asked: 2020-08-21 04:21:05 +0800 CST2020-08-21 04:21:05 +0800 CST 2020-08-21 04:21:05 +0800 CST

为什么 SQL 开发人员建议为有效的过程使用不同的格式?

  • 772

这是我的原始程序,效果很好:

create or replace PROCEDURE EXTRACT_0_CPP AS
    CURSOR c_data IS
        SELECT cpp,
               rfu1,
               rfu2,
               mean_rfu,
               charge_ph7_4,
               hydropathy
        FROM   cpp
        ORDER BY LENGTH(cpp);
    F1 UTL_FILE.FILE_TYPE;

BEGIN 
    F1 := UTL_FILE.FOPEN( location => 'EXTRACT_DIR',
                          filename => '0_cpp.TXT',
                          open_mode => 'w',
                          max_linesize => 32767);
    FOR cur_rec IN c_data LOOP 
        UTL_FILE.PUT_LINE (F1, 
                            cur_rec.cpp || ':' ||
                            cur_rec.rfu1 || ':' ||
                            cur_rec.rfu2 || ':' ||
                            cur_rec.mean_rfu || ':' ||
                            cur_rec.charge_ph7_4 || ':' ||
                            cur_rec.hydropathy);                     
    END LOOP;
    UTL_FILE.FCLOSE(F1);
END;

但是 SQL Developer 在下面给了我一条弯曲的红线,SELECT并建议我将其更改为:

create or replace PROCEDURE EXTRACT_0_CPP AS
    CURSOR c_data IS
        SELECT
    "A1"."CPP"         "CPP",
    "A1"."RFU1"           "RFU1",
    "A1"."RFU2"           "RFU2",
    "A1"."MEAN_RFU"       "MEAN_RFU",
    "A1"."CHARGE_PH7_4"   "CHARGE_PH7_4",
    "A1"."HYDROPATHY"     "HYDROPATHY"
FROM
    "C##ELLIE"."CPP" "A1"
ORDER BY
    length("A1"."CPP");
    F1 UTL_FILE.FILE_TYPE;

BEGIN 
    F1 := UTL_FILE.FOPEN( location => 'EXTRACT_DIR',
                          filename => '0_cpp.TXT',
                          open_mode => 'w',
                          max_linesize => 32767);
    FOR cur_rec IN c_data LOOP 
        UTL_FILE.PUT_LINE (F1, 
                            cur_rec.pk_cpp || ':' ||
                            cur_rec.rfu1 || ':' ||
                            cur_rec.rfu2 || ':' ||
                            cur_rec.mean_rfu || ':' ||
                            cur_rec.charge_ph7_4 || ':' ||
                            cur_rec.hydropathy);                     
    END LOOP;
    UTL_FILE.FCLOSE(F1);
END;

我的问题是(为什么)这更好?什么是“A1”?

oracle
  • 4 4 个回答
  • 1391 Views

4 个回答

  • Voted
  1. William Robertson
    2020-08-21T06:49:18+08:002020-08-21T06:49:18+08:00

    关于为什么在代码已经工作时它会建议一种不同的格式,当然有可能有格式不好的代码可以工作,所以原则上你没有理由不考虑布局或重构改进,这可能会使代码更健壮、更高效或更易于维护。

    但是,双引号的名称是不好的做法,因为它们隐藏了命名错误并强制您指定大写/小写,并且结果比原来的可读性差。它们确实是一种可移植性功能,可用于具有奇怪表名的第三方应用程序。代码生成器倾向于在所有内容周围加上双引号,因为这样做比检测每种情况下是否真的需要它们更容易。没有办法

    from "C##ELLIE"."CPP" "A1"
    

    是否有任何改进

    from cpp
    

    除了使用表别名之外。给表一个别名(不带双引号!)并在引用列时使用它是个好主意。但是"A1"(或什至a1)是只有计算机才能想到的那种表别名。使用表名的某种缩写形式的别名会好得多,也许在这种情况下c。想象一下,如果您要加入六张桌子 - 现在是哪一张a3?哦,对了,就是ORDER_DETAILS。(虽然在这种情况下,表名很短,没有必要给它起别名。)所以,

    SELECT "A1"."CPP" "CPP"
    FROM   "C##ELLIE"."CPP" "A1"
    

    会好得多

    SELECT c.cpp
    FROM   cpp c
    

    (我也会小写它,因为这不是 1974 年,我的编辑器使用颜色和粗体突出显示语言关键字,但我们会放手。)

    硬编码模式名称是不好的做法,因为它充其量是多余的(对象在您已经在使用的模式中,因此除了不必要的复杂性之外它不​​会增加任何内容)或更糟糕的是,它会限制可移植性(如果您曾经重命名模式或移动您的代码)必须通过它清理硬编码的引用)。

    我确信这是一个很好的聪明功能,但在这种情况下,这不是一个好的建议。

    • 5
  2. Best Answer
    nbk
    2020-08-21T05:04:43+08:002020-08-21T05:04:43+08:00

    A1是表的别名"C##ELLIE"."CPP"

    过程是相同的,但是你和 oracle 也知道表 cpp 属于哪个模式。

    另外,您还应该添加注释该程序的作用,如果您在 3 年后回来,则更容易知道您使用的架构以及它的用途

    • 4
  3. EdStevens
    2020-08-21T09:27:03+08:002020-08-21T09:27:03+08:00

    这是一个关于在对象名称周围使用双引号有什么问题的演示。仔细阅读每个命令并注意表名的大小写敏感,引用和不引用。

    SQL> create table test_table_1 (dob date);
    
    Table created.
    
    SQL> create table "test_table_2" ("dob" date);
    
    Table created.
    
    SQL> select * from test_table_1;
    
    no rows selected
    
    SQL> select * from test_table_2;
    select * from test_table_2
                  *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    
    
    SQL> select * from "test_table_2";
    
    no rows selected
    
    SQL> 
    SQL> select table_name
      2  from user_tables
      3  where upper(table_name) like 'TEST_TABLE%'
      4  order by table_name;
    
    TABLE_NAME
    --------------------------------------------------------------------------------
    TEST_TABLE_1
    test_table_2
    
    2 rows selected.
    
    SQL> 
    SQL> drop table test_table_1;
    
    Table dropped.
    
    SQL> drop table test_table_2;
    drop table test_table_2
               *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    
    
    SQL> drop table "test_table_2";
    
    Table dropped.
    
    SQL> --
    SQL> spo off
    
    • 4
  4. Caius Jard
    2020-08-22T02:11:20+08:002020-08-22T02:11:20+08:00

    我可能会为您的代码推荐这个:

    ...
        CURSOR c_data IS
            SELECT c.cpp,
                   c.rfu1,
                   c.rfu2,
                   c.mean_rfu,
                   c.charge_ph7_4,
                   c.hydropathy
            FROM   cpp c
            ORDER BY LENGTH(c.cpp);
    ...
    

    我们只使用一个表/视图,cpp所以别名不是绝对必要的,但如果将来另一个表添加到这个查询中会很有帮助。

    特别是对于 2+ 表查询,如果 SELECT 中的名称不是完全限定的(在列名之前提及表名或别名),那么如果将列添加到与另一个表中的另一列同名的表中,查询可能会中断桌子:

    PersonTable: id, name, status, addressid
    AddressTable id, street
    
    --this is ok for now
    SELECT name, status, street FROM person INNER JOIN street ON person.addressid = address.id
    

    如果我们向地址添加一个状态列,上述查询将失败,因为它现在不明确。添加导致此类问题的列不会让数据库宣布“我添加了它,但顺便说一下,整个架构和依赖系统中的所有其他查询现在都将失败” - 你只需要找到那些通过测试失败的查询。或客户抱怨;)

    如果我们完全限定它:

    SELECT 
      person.name, 
      person.status, 
      address.street 
    FROM 
      person 
      INNER JOIN adress a ON person.addressid = address.id
    

    它会继续工作..

    用列重复表名有点乏味和罗嗦。使用较短的名称不仅可以提高可读性..

    SELECT 
      p.name, 
      p.status, 
      a.street 
    FROM 
      person p
      INNER JOIN address a ON p.addressid = a.id
    

    ..但在心理上提醒我们,我们可以出于不同的原因多次加入表:

     SELECT 
      p.name, 
      p.status, 
      a_work.street as workstreet,
      a_home.street as homestreet
    FROM 
      person p
      INNER JOIN address a_work ON p.work_addressid = a.id --note, i've silently upgraded Person here to track two addresses
      INNER JOIN address a_home ON p.home_addressid = a.id
    

    总而言之,SQLDeveloper 正在尝试做一件好事,因为它正在朝着以下方面迈进:

    • 给你的表一个合理的、可读的、上下文相关的别名
    • 始终使用别名完全限定您的列名

    它掉下来的地方是:

    • 它选择了一个废话别名A1,这无助于您记住任何东西;p我选择人员和地址绝非偶然,我a相信你会欣赏的。如果有一个派对和一个项目要加入,我可能会使用per,pro和par. 我会避免pr,因为 Person、Party 和 Project 在单词中都有p和r作为相关的初始辅音,所以pr不要像使用三个字母那样明显地喊出“它是 PRoject 的别名”(但我当然会接受你的争论pe,如果你想节省一些击键:) pa)pr
    • 它在各处盲目地加双引号,可能是“为了安全”,但也因为它是阻力最小的路径 - 编写一个盲目添加引号的逻辑builder.addcolumn( '"' || alias_name || '"."' || col_name || '",')比检查列名并查看它是否需要要容易得多引用并仅在需要时添加它们。不幸的是,这意味着代码最终"到处都是不可读的混乱......
    • ..并从“只是盲目地引用所有内容”开始是“然后将所有标识符全部大写,因为现在表/列名称不区分大小写。SELECT pErSon.NaME ...很好;即使table.column只是PERSON。 NAME 不区分大小写。但是当我们盲目地添加引号时,我们绝对必须将名称全部大写,因为添加引号会使它们以区分大小写的方式处理!SELECT "pErSon"."NaME"只是行不通,所以你仔细写出来,漂亮可读的*小写标识符不见了..

    SQLDeveloper 真的可以进行所有内省和逻辑来确定需要引用的内容,无论是因为时髦的字符、空格、大小写等。但它没有——它采用安全和简单的编码方法,比如“只是引用它”,“只是大写它”和“只是创建一个随机/增量独特的别名”,不幸的是,这是一个糟糕的建议,尽管它正在尝试的一些精神是一个好主意

    *作为孩子,我们先学习小写字母;我们读小写句子的速度总是比大写的快

    • 1

相关问题

  • Oracle 中的数据库备份 - 导出数据库还是使用其他工具?

  • ORDER BY 使用文本列的自定义优先级

  • 舒服的sqlplus界面?[关闭]

  • 如何在数据库中找到最新的 SQL 语句?

  • 如何使用正则表达式查询名称?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve