Relação de tabela conhecida: como mostrado abaixo
Expectativa: retornar os registros dos exames de todos os alunos na forma de uma tabela: assunto como cabeçalho horizontal e nome como cabeçalho vertical, como mostrado abaixo
Existem duas etapas principais
Etapa 1: Crie uma nova tabela ( test_info ) com o assunto como a coluna , a operação é a seguinte
Para um caso detalhado, consulte https://blog.csdn.net/super_DuoLa/article/details/103199300
1. Abra o PL / SQL, localize " Procedimentos ", clique com o botão direito do mouse em " Novo ... ", o seguinte conteúdo será exibido, preencha o conteúdo necessário de acordo com o formato
2. Clique em "OK" para entrar no processo de armazenamento e começar a escrever o código.
create or replace procedure testTable(graId VARCHAR2) is
str1 varchar2(4000); --获取建表所需数据的SQL语句
str2 varchar2(200); --用于存放 原数据中的单个元素
ds sys_refcursor; --游标,指针用于循环
createsql varchar2(4000); --创建新表
a number; --表存在的个数
dl varchar2(4000); --删除表
dorpsql varchar2(4000); --验证表是否存在
begin
DBMS_OUTPUT.ENABLE(buffer_size => null);
str1:='SELECT DISTINCT subname from msubject where graid='''||graId||''''; --所需数据
dl:='drop table test_info'; --删除表
createsql:='create table test_info(姓名 varchar2(4000),合计 varchar2(4000)';
open ds for str1; --将获取到的原数据进行循环,ds作为过渡元素使用
LOOP
FETCH ds INTO str2; --将ds中的结果依次插入到str2中
EXIT WHEN ds%NOTFOUND; --没有数据的时候,循环结束
createsql:=createsql||','||str2||' varchar2(4000)'; --拼接字符串【原数据中的元素】
END LOOP;
CLOSE ds;
createsql:=createsql||')';
dorpsql:='select count(*) from user_tables where TABLE_NAME =upper(''test_info'')'; --查表
execute immediate dorpsql into a; --将查询是否存在的结果赋值给计数变量a
if a = 1 then --表存在
execute immediate dl; --执行删除语句
end if;
dbms_output.put_line(createsql); --打印语句
execute immediate createsql; --执行创建新表的语句
end testTable;
3, após a conclusão do procedimento armazenado preparação é executada: clique abaixo da engrenagem do anel amarelo-se a
4. Ligue para o procedimento armazenado (o formato da chamada é diferente em mybatis, consulte para obter detalhes)
--语法 call 方法名称(参数)
call testTable('11111')
5. Após a execução bem-sucedida, visualize os resultados
Neste ponto, o uso dos resultados da consulta como novos nomes de coluna para criar dinamicamente a estrutura da tabela está concluído.
Etapa 2: escreva um procedimento armazenado para obter o resultado
1. Encontre " Pacotes ", clique com o botão direito do mouse em " Novo ... ", o seguinte conteúdo aparece, preencha o conteúdo necessário de acordo com o formato
2. Diferentemente do procedimento armazenado básico, o procedimento armazenado é criado em Pacotes.O procedimento armazenado é dividido em duas partes , uma em "Pacotes" e outra em "Corpos de pacotes" Mostrado
3. Após entender a estrutura básica, inicie a programação: dividida em duas partes
create or replace package testRecords is
-- Author : ADMIN
-- Created : 2019/11/27 14:07:47
-- Purpose : 学生的考试记录
TYPE testdata IS TABLE of test_info%rowtype; --返回结果testdata是表test_info类型
--实现的方法(参数是年级)
function mResult(graId VARCHAR2) return testdata PIPELINED;
end testRecords;
create or replace package body testRecords is
--获取学生的考试记录
function mResult(graId VARCHAR2) return testdata PIPELINED is
str varchar2(4000);--存放“课程”查询语句
transition varchar2(4000);--循环
ds sys_refcursor;--游标
rests test_info%rowtype;--结果行
mstr LONG; --结果SQL语句
begin
DBMS_OUTPUT.ENABLE(buffer_size => null);
str:='SELECT DISTINCT subname from msubject where graid='''||graId||'''';
mstr:='select MAX (U . NAME) AS 姓名,COUNT (a. ID) AS 合计';
open ds for str; --将str中的值赋值给ds
LOOP
FETCH ds INTO transition; --循环ds,并依次将值赋给transition
EXIT WHEN ds%NOTFOUND; --没有数据的时候,循环结束
mstr:=mstr||',COUNT(CASE WHEN subname ='''||transition||''' THEN 1 END) AS "'||transition||'"'; --如果满足学生与学科对应,则+1
END LOOP;
CLOSE ds;
mstr:=mstr||' FROM MUSER U LEFT JOIN (SELECT * FROM MRECORDS) A ON u.id=a.usid LEFT JOIN MSUBJECT b ON b.ID = a.subname WHERE b.graid='''||graId||''' GROUP BY U . ID';
dbms_output.put_line(mstr); --打印语句【相当于Java中的 System.out.print()】
open ds for mstr; --将查询到的结果集赋值给临时变量ds
LOOP
FETCH ds INTO rests; --将结果集循环插入到rests结果行中
EXIT WHEN ds%NOTFOUND;
PIPE ROW(rests); --多个结果行最终会返回结果行集合,即生成表格 【PIPE:管道函数即是可以返回行集合】
END LOOP;
CLOSE ds;
return;
end;
end testRecords;
4. Execute o procedimento armazenado, da mesma forma que a operação na primeira etapa .
5. Procedimento armazenado de chamada (mesmo formato de chamada em mybatis)
--语法 select * FROM table(名称.方法名(参数))
select * FROM table(testrecords.mResult('11111'))
6. Visualizar resultados: Após a execução bem-sucedida, os seguintes resultados aparecerão no console
PS: Clique na etiqueta circulada na figura acima para visualizar os resultados impressos durante o processo de armazenamento, conforme mostrado abaixo
Até agora: " Os registros de teste do aluno são retornados à tabela como dados ". As explicações / comentários no artigo baseiam-se na compreensão pessoal.Se houver algo errado, obrigado por me corrigir!