plsql - 更改 oracle 输出结果的方式

标签 plsql oracle11g dynamic-sql toad

请仔细阅读,如果您不明白我在说什么,请告诉我。

下面是表名称和这些表中的列

表格:SYSTEM_USER_SKILL

    user_id
    skill_id
    user_abilities

表: SYSTEM_ADMIN_SKILL

skill_id
skill_name

表: SYSTEM_USER

user_id
user_full_name

我想编写一个动态sql或pl/sql来显示user_full_name和user_ability。

但我希望它像这样显示:

enter image description here

附:您可以在其中看到“Y”和“N”,这些是 user_bility 的结果

我不知道如何做到这一点,我只知道它可以使用动态 sql 或 pl/sql 来完成

最佳答案

只要您使用的是 Oracle 11gR2,就可以使用pivot 来获取表格形式的数据:

select * from (
  select su.user_full_name, sas.skill_name, sus.user_abilities
  from system_user su
  cross join system_admin_skill sas
  left join system_user_skill sus on sus.user_id = su.user_id
    and sus.skill_id = sas.skill_id
) pivot (max(user_abilities) as able for (skill_name)
    in ('php' as php, 'java' as java, 'pl/sql / sql' as plsql_sql,
      'Oracle apex' as oracle_apex));

USER_FULL_NAME       PHP_ABLE JAVA_ABLE PLSQL_SQL_ABLE ORACLE_APEX_ABLE
-------------------- -------- --------- -------------- ----------------
Sarah woods          N        N         Y              Y                
John brown           N        Y         Y              Y                
Johnny paterson      Y        Y         Y              Y                
Amy brown            N        N         Y              N                

但您需要在 in 子句中明确列出每项技能。 SQL Fiddle .

在 SQL*Plus 或 SQL Developer 中,您可以通过以下方式获得所需的标题:

column user_full_name heading "Name"
column php_able format a15 heading "php"
column java_able format a15 heading "java"
column plsql_sql_able format a15 heading "pl/sql / sql"
column oracle_apex_able format a15 heading "Oracle apex"

select ...

Name                 php             java            pl/sql / sql    Oracle apex   
-------------------- --------------- --------------- --------------- ---------------
Sarah woods          N               N               Y               Y               
John brown           N               Y               Y               Y               
Johnny paterson      Y               Y               Y               Y               
Amy brown            N               N               Y               N               

...但我不知道 Toad 是否有类似的东西。


与此等效的非枢轴,您必须在旧版本中使用,如下所示:

select su.user_id, su.user_full_name,
  max(case when sas.skill_id = 1 then sus.user_abilities end) as php,
  max(case when sas.skill_id = 2 then sus.user_abilities end) as java,
  max(case when sas.skill_id = 3 then sus.user_abilities end) as plsql_sql,
  max(case when sas.skill_id = 4 then sus.user_abilities end) as oracle_apex
from system_user su
cross join system_admin_skill sas
left join system_user_skill sus on sus.user_id = su.user_id
  and sus.skill_id = sas.skill_id
group by su.user_id, su.user_full_name;

这仍然具有硬编码的所有技能。为了允许额外的技能而无需修改查询,您需要动态构建它,如评论中链接的早期答案所示。在这种特定情况下,您可以执行以下操作:

create or replace function get_skill_matrix return sys_refcursor as
  query varchar2(32767);
  rc sys_refcursor;
begin
  query := 'select su.user_id, su.user_full_name';
  for tmp in (select skill_id, skill_name from system_admin_skill
      order by skill_id)
  loop
    query := query || ', max(case when sas.skill_id = ' || tmp.skill_id
      || ' then sus.user_abilities end) as "'
      || substr(tmp.skill_name, 1, 30) || '"';
  end loop;
  query := query || ' from system_user su';
  query := query || ' cross join system_admin_skill sas';
  query := query || ' left join system_user_skill sus on sus.user_id = su.user_id';
  query := query || ' and sus.skill_id = sas.skill_id';
  query := query || ' group by su.user_id, su.user_full_name';

  open rc for query;

  return rc;
end;
/

用于动态 SQL 的 query 字符串只是构建为看起来与静态版本完全相同,但每个 skill_id 特定子句是在循环中生成的来自基本 system_admin_skill 表。

当你调用这个函数时,你会得到一个光标。您还没有真正说明如何或在何处使用结果。您可以将其视为 Java 程序中的结果集,例如,通过执行该函数,然后在语句对象上调用 getCursor()。在 SQL*Plus 或 SQL Developer 中,您可以使用 variableprint 命令来显示它:

var rc refcursor;
exec :rc := get_skill_matrix;
print rc

在 SQL Developer 中给出:

anonymous block completed
RC
----------------------------------------------------------------------------------------------
USER_ID                                 USER_FULL_NAME       java php pl/sql / sql Oracle apex 
--------------------------------------- -------------------- ---- --- ------------ ----------- 
3                                       Amy brown            N    N   Y            N           
4                                       Sarah woods          N    N   Y            Y           
2                                       Johnny paterson      Y    Y   Y            Y           
1                                       John brown           Y    N   Y            Y           

或者在 SQL*Plus 中,您可以执行column user_id noprint 来隐藏 ID(我已经将其包含在内,以防两个人同名!):

Name                 j p p O
-------------------- - - - -
Amy brown            N N Y N
Sarah woods          N N Y Y
Johnny paterson      Y Y Y Y
John brown           Y N Y Y

在 Toad 中,我认为你可以做到这一点,这就是 exec 正在做的所有事情:

开始 :rc := get_skill_matrix; 结束;

...它会提示您输入 :rc 的绑定(bind)类型;如果您选择“引用光标”,它将在数据网格中显示结果。 Apparently .


好的,同样的事情,但没有函数(但仍然是 PL/SQL),并在截断之前将技能 ID 包含在列别名中以使其唯一:

var rc refcursor

declare
  query varchar2(32767);
begin
  query := 'select su.user_id, su.user_full_name as "Name"';
  for tmp in (select skill_id, skill_name from system_admin_skill
      order by skill_id) loop
    query := query || ', max(case when sas.skill_id = ' || tmp.skill_id
      || ' then sus.user_abilities end) as "'
      || substr(tmp.skill_id || ' ' || tmp.skill_name, 1, 30) || '"';
  end loop;
  query := query || ' from system_user su';
  query := query || ' cross join system_admin_skill sas';
  query := query || ' left join system_user_skill sus on sus.user_id = su.user_id';
  query := query || ' and sus.skill_id = sas.skill_id';
  query := query || ' group by su.user_id, su.user_full_name';

  open :rc for query;
end;
/

print rc

这给出:

RC
-----------------------------------------------------------------------------
USER_ID        Name                 1 java 2 php 3 pl/sql / sql 4 Oracle apex 
-------------- -------------------- ------ ----- -------------- ------------- 
3              Amy brown            N      N     Y              N             
4              Sarah woods          N      N     Y              Y             
2              Johnny paterson      Y      Y     Y              Y             
1              John brown           Y      N     Y              Y             

关于plsql - 更改 oracle 输出结果的方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21557486/

相关文章:

sql - 如何将 PLSQL 参数 (:old. numero) 放入 UTL_HTTP.REQUEST 语句中?

oracle - 回滚+提交一些更改

tsql - 用于分页的公用表中的 T-SQL 动态排序依据

sql-server-2008 - SQL Server 2008 - 过多的非规范化和过度索引 : What use is there for the Matrix?

java - 从 Java 访问存储过程的 %ROWTYPE

c# - 使用 Oracle.ManagedAccess 使用存储过程执行内联语句

sql - 如何更新 Oracle 表中的 bool 字段

excel - [Microsoft][ODBC Driver Manager]未找到数据源名称且未指定默认驱动程序

java - 无法打开连接异常: Generic JDBC Exception

oracle - ORA-01007 "variable not in select list"来自 dbms_sql.column_value 调用