Uma View ou visão em português, é uma tabela virtual. A View não possui um armazenamento de dados permanente associado a ela, mas é baseada em outra tabela ou tabelas. Existem vários tipos de visões, elas podem variar suas funcionalidades de banco de dados para banco de dados, as Views mais comum são do tipo padrão, particionada ou materializada.
A visão fornece uma forma alternativa de olhar os dados em uma ou mais tabelas. A vista é uma especificação chamada de uma tabela de resultados. Conceitualmente, a criação de um ponto de vista é como o uso de binóculos. Você pode olhar através de binóculos para ver uma paisagem inteira ou olhar para uma imagem específica dentro da paisagem, como uma árvore. Da mesma forma, você pode criar uma visão que combina dados de diferentes tabelas de base ou criar uma visão limitada de uma tabela que omite dados. Na verdade, estes são os motivos mais comuns para usar um ponto de vista. Combinando informações de tabelas de base simplifica a obtenção de dados para o usuário final, e limitar os dados que um usuário pode ver é útil para fins de segurança.
Devido aos vários tipos diferentes de Views e suas respectivas diferenças de funcionalidades entre os bancos de dados Oracle, IBM DB2 e MSSQL é recomendado que você utilize os links oficiais para referencia:
Oracle: Create View
IBM DB2: Create View
Microsoft SQL Server: Create View
Algo Extremamente Útil Sobre Views
As Views são essenciais para uma boa performance de um sistema que manipula dados, elas são uteis de muitas maneiras diferentes, todos os sistemas de grande porte utilizam tipos de View.
As Views acrescentam performance a aplicação, podem conter constraints e índices, podem criar visões baseadas em formato XML, podem ser utilizadas para fins de segurança, podem ser criadas a partir de tabelas particionadas alocadas em vários servidores diferentes e retornar uma visão única, são fundamentais na criação de complexos relatórios, modelo de dados para exportação e até no manuseio de cadastros.
As Views possuem um recurso muito útil quando unidas ao evento INSTEAD OF de uma Trigger, na verdade este tipo de evento foi desenvolvido especialmente para a utilização em conjunto com uma View (exceto para banco de dados MSSQL que permite o uso em tabelas comuns). A utilização do evento “ao invés de” em uma View permite que o desenvolvedor ganhe a maior performance possível na distribuição de dados baseados em uma única visão para varias tabelas físicas contidas em locais diferentes.
Isto acontece porque, por exemplo, um formulário de cadastramento complexo geralmente é composto de varias tabelas interligadas pelo seu identificador, a combinação View–Trigger permite que você retorne em uma única pesquisa todo o cadastro utilizando um único acesso. Quando disparado um evento para criar um cadastro novo ou modificar um cadastro existente em cima de uma View, automaticamente uma Trigger “ao invés de inserir” ou “ao invés de alterar” pode distribuir todos os dados alimentados pelo usuário em cada tabela especifica, tendo em seu beneficio, que todo o processo esta sendo efetuado dentro do motor do banco de dados.
Eclipse – Java
Para conectar aos diversos bancos de dados em um único programa você precisa referenciar os drivers contidos em JARs externos, você encontra um walkthrough de como instalar os bancos de dados, seus drivers e a configuração da IDE Eclipse na categoria SQL e Java, use a imagem abaixo para referencia deste procedimento:
Exemplo:
Neste exemplo utilizamos o conceito básico de uma View em conjunto com o evento INSTEAD OF de uma Trigger, no programa abaixo o método de inserção esta completo, fica como exercício criar o método INSTEAD OF UPDATE e INSTEAD OF DELETE.
Você encontra uma visão contendo duas tabelas relacionadas, a tabela Funcionários e Desconto, e a partir de uma trigger utilizamos o evento “ao invés de inserir” para distribuir os dados para suas respectivas tabelas. Na aplicação Java o campo porcentagem possui cor diferente pois se encontra em outra tabela, você pode utilizar este exemplo básico para criar cadastros mais complexos.
* Para referencia sobre as triggers utilize nosso post Java com o tópico Triggers.
** Você encontra este mesmo programa utilizando SQL direto na aplicação, clicando aqui.
SQL
Oracle
-- Cria tabela de funcionarios create table Funcionarios( ID_Funcionario NUMBER(5), Nome VARCHAR2(30), Sobrenome VARCHAR2(70), Cargo VARCHAR2(30), Salario NUMBER(9,2)); -- Cria tabela com a porcentagem de descontos Create table DESCONTO ( ID_FUNCIONARIO NUMBER, PORCENTAGEM NUMBER(9,2)); -- Cria View (Visão) do Cadastro de funcionarios Create or Replace View CadFuncionario as Select A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME, A.CARGO, A.SALARIO, B.PORCENTAGEM from FUNCIONARIOS A, DESCONTO B Where A.ID_FUNCIONARIO = B.ID_FUNCIONARIO; -- Cria Trigger Ao inves de inserir sobre a View create or replace TRIGGER CADFUNC_INSERT INSTEAD OF INSERT ON CadFuncionario FOR EACH ROW BEGIN -- Insere dados na tabela de Funcionario Insert into FUNCIONARIOS values ( :new.ID_FUNCIONARIO, :new.NOME, :new.SOBRENOME, :new.CARGO, :new.SALARIO); -- Insere dados na tabela de Desconto Insert into DESCONTO values ( :new.ID_FUNCIONARIO, :new.PORCENTAGEM); END CADFUNC_INSERT;
IBM DB2
-- Desenvolvimento Aberto -- -- Atente-se para o terminador de instruções -- o IBM DATA STUDIO não consegue utilizar -- Begin... END com scripts sql -- Mude o terminador para o caractere @ -- para mudar clique com o botão direito do mouse aqui!!! -- Cria tabela de funcionarios create table Funcionarios ( ID_Funcionario INTEGER, Nome VARCHAR(30), Sobrenome VARCHAR(70), Cargo VARCHAR(30), Salario NUMERIC(9,2))@ -- Cria tabela com a porcentagem de descontos Create table DESCONTO ( ID_FUNCIONARIO INTEGER, PORCENTAGEM DECIMAL(9,2))@ -- Cria View (Visão) do Cadastro de funcionarios Create or Replace View CadFuncionario as Select A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME, A.CARGO, A.SALARIO, B.PORCENTAGEM from FUNCIONARIOS A, DESCONTO B Where A.ID_FUNCIONARIO = B.ID_FUNCIONARIO@ -- Cria Trigger Ao inves de inserir sobre a View create or replace TRIGGER CADFUNC_INSERT INSTEAD OF INSERT ON CadFuncionario REFERENCING NEW AS N FOR EACH ROW T1: BEGIN -- Insere dados na tabela de Funcionario Insert into FUNCIONARIOS values ( N.ID_FUNCIONARIO, N.NOME, N.SOBRENOME, N.CARGO, N.SALARIO); -- Insere dados na tabela de Desconto Insert into DESCONTO values ( N.ID_FUNCIONARIO, N.PORCENTAGEM); END T1
MSSQL Server
-- Cria tabela de funcionarios create table Funcionarios ( ID_Funcionario Int, Nome VARCHAR(30), Sobrenome VARCHAR(70), Cargo VARCHAR(30), Salario Decimal(9,2)); -- Cria tabela com a porcentagem de descontos Create table DESCONTO ( ID_FUNCIONARIO INT, PORCENTAGEM DECIMAL(9,2)); -- Cria View (Visão) do Cadastro de funcionarios Create View CadFuncionario as Select A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME, A.CARGO, A.SALARIO, B.PORCENTAGEM from FUNCIONARIOS A, DESCONTO B Where A.ID_FUNCIONARIO = B.ID_FUNCIONARIO; -- Cria Trigger Ao inves de inserir sobre a View create Trigger CADFUNC_INSERT ON CadFuncionario INSTEAD OF INSERT as BEGIN -- Insere dados na tabela de Funcionario Insert into FUNCIONARIOS Select ID_FUNCIONARIO, NOME, SOBRENOME, CARGO, SALARIO from inserted; -- Insere dados na tabela de Desconto Insert into DESCONTO Select ID_FUNCIONARIO, PORCENTAGEM from inserted END;
Java
import java.awt.Color; import java.awt.ComponentOrientation; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.Border; import javax.swing.border.EtchedBorder; public class MinhaView implements ActionListener { // Declara componentes private JLabel ltitulo; private JLabel lid; private JLabel lpnome; private JLabel lsnome; private JLabel lcargo; private JLabel lsalario; private JLabel lpesquisa; private JLabel lporcentagem; private JTextField tid; private JTextField tpnome; private JTextField tsnome; private JTextField tcargo; private JTextField tsalario; private JTextField tpesquisa; private JTextField tporcentagem; private JButton botao; private JButton alterar; private JButton inserir; private JButton deletar; private JButton novo; private Border borda; private JFrame menssagem; // Declara objetos de conexão private static Connection conn; private static Statement query; // Declara variaveis private static String bconexao; // Cria conexão public void conectar(String banco) { // Verifica strings de conexão // ORACLE if (banco == "oracle") { try { // Define Driver de conexão JDBC thin Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "daberto", "p@55w0rd"); // Executa pedido SQL query = conn.createStatement(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } } // DB2 if (banco == "db2") { try { // Define Driver de conexão JDBC Class.forName("com.ibm.db2.jcc.DB2Driver"); conn = DriverManager.getConnection( "jdbc:derby:net://localhost:50000/deva", "db2admin", "p@55w0rd"); // Executa pedido SQL query = conn.createStatement(); // JOptionPane.showMessageDialog(menssagem, // "Conexão Efetuada com sucesso!"); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (SQLException ex) { // JOptionPane.showMessageDialog(menssagem, "Erro na conexão!"); ex.printStackTrace(); } } // MICROSOFT SQL SERVER if (banco == "mssql") { try { // Define Driver de conexão JDBC String URL = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=devaberto" + ";user=devaberto;password=p@55w0rd"; Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); conn = DriverManager.getConnection(URL); // Executa pedido SQL query = conn.createStatement(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } } } // Retorna funcionario public ResultSet retornaFuncionarioId(String codigo) throws SQLException { // Cria uma nova conexão Statement query; query = conn.createStatement(); String sql; // Verfica banco de dados e passa script SQL sql = "Select * From CadFuncionario Where ID_FUNCIONARIO = " + codigo; // Executa Script ResultSet dados = query.executeQuery(sql); // Retorna set de dados return dados; } public Container criaPainel() { // cria painel JPanel painel = new JPanel(); painel.setLayout(new FlowLayout()); painel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); painel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); // Cria titulo ltitulo = new JLabel("Database - Cadastro de Funcionário -Sem conexão"); painel.add(ltitulo); painel.add(Box.createVerticalStrut(60)); // Cria painel de usuario JPanel painelDados = new JPanel(new GridLayout(0, 2, 10, 10)); // Cria componentes // Tabela de Funcionarios lid = new JLabel("Código:"); lpnome = new JLabel("Primeiro Nome:"); lsnome = new JLabel("Sobrenome:"); lcargo = new JLabel("Cargo:"); lsalario = new JLabel("Salário:"); tid = new JTextField(); tpnome = new JTextField(); tsnome = new JTextField(); tcargo = new JTextField(); tsalario = new JTextField(); // Tabela de Desconto lporcentagem = new JLabel("Porcentagem (%):"); tporcentagem = new JTextField(); lporcentagem.setForeground(Color.BLUE); tid.setPreferredSize(new Dimension(150, 20)); // Adiciona componentes no painel painelDados.add(Box.createVerticalStrut(10)); painelDados.add(Box.createVerticalStrut(10)); painelDados.add(lid); painelDados.add(tid); painelDados.add(lpnome); painelDados.add(tpnome); painelDados.add(lsnome); painelDados.add(tsnome); painelDados.add(lcargo); painelDados.add(tcargo); painelDados.add(lsalario); painelDados.add(tsalario); painelDados.add(lporcentagem); painelDados.add(tporcentagem); painelDados.add(Box.createVerticalStrut(10)); painelDados.add(Box.createVerticalStrut(10)); // Cria painel de pesquisa JPanel painelPesquisa = new JPanel(new GridLayout(0, 3, 10, 10)); borda = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED); painelPesquisa.setBorder(borda); // Cria pesquisas lpesquisa = new JLabel("Pesquisa código:"); tpesquisa = new JTextField(); botao = new JButton("Pesquisar"); botao.addActionListener(this); // Define foco do cursor no campo de pesquisa javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { tpesquisa.requestFocus(); } }); // Adiciona compoentes ao painel de pesquisa painelPesquisa.add(lpesquisa); painelPesquisa.add(tpesquisa); painelPesquisa.add(botao); // Cria painel de pesquisa JPanel painelAcao = new JPanel(new GridLayout(0, 4, 10, 10)); borda = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED); painelAcao.setBorder(borda); // Cria botões de manipulação de banco novo = new JButton("Novo"); inserir = new JButton("Inserir"); alterar = new JButton("Alterar"); deletar = new JButton("Apagar"); // Cria ouvintes de eventos novo.addActionListener(this); inserir.addActionListener(this); alterar.addActionListener(this); deletar.addActionListener(this); // Insere componentes em um painel painelAcao.add(novo); painelAcao.add(inserir); painelAcao.add(alterar); painelAcao.add(deletar); // Adiciona paineis painel.add(painelPesquisa); painel.add(painelDados); painel.add(painelAcao); return painel; } // Clique do botão de pesquisa public void actionPerformed(ActionEvent arg0) { // Verifica pesquisa if (arg0.getSource() == botao) { // Cria instancia de objeto MinhaView campos = new MinhaView(); // retorna result de dados try { ResultSet dados = campos.retornaFuncionarioId(tpesquisa .getText()); ltitulo.setText("Database - Cadastro de Funcionário - " + bconexao); // Preenche campos da tela while (dados.next()) { tid.setText(dados.getString("ID_FUNCIONARIO")); tpnome.setText(dados.getString("NOME")); tsnome.setText(dados.getString("SOBRENOME")); tcargo.setText(dados.getString("CARGO")); tsalario.setText(dados.getString("SALARIO")); tporcentagem.setText(dados.getString("PORCENTAGEM")); } } catch (SQLException e) { e.printStackTrace(); } } // Botão Novo if (arg0.getSource() == novo) { tid.setText(null); tpnome.setText(null); tsnome.setText(null); tcargo.setText(null); tsalario.setText(null); tporcentagem.setText(null); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { tid.requestFocus(); } }); } // Insere dados if (arg0.getSource() == inserir) { String sql = "Insert into CadFuncionario " + " (ID_FUNCIONARIO, NOME, SOBRENOME, CARGO, SALARIO, PORCENTAGEM) " + "values (" + tid.getText() + ", " + "\'" + tpnome.getText() + "\', " + "\'" + tsnome.getText() + "\', " + "\'" + tcargo.getText() + "\', " + tsalario.getText() + ", " + tporcentagem.getText() + ")"; try { query.execute(sql); JOptionPane.showMessageDialog(menssagem, "Dados inserido com sucesso!"); } catch (SQLException e) { JOptionPane.showMessageDialog(menssagem, e.toString()); e.printStackTrace(); } } // Altera dados if (arg0.getSource() == alterar) { // TODO: Criar uma Trigger como evento INSTEAD OF UPDATE } // Deleta dados if (arg0.getSource() == deletar) { // TODO: Criar uma Trigger com o evento INSTEAD OF DELETE } } public static void criaGUI() { // Cria formulario JFrame formulario = new JFrame("Desenvolvimento Aberto"); formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // cria painel de conteudo MinhaView acesso = new MinhaView(); // conecta ao banco de dados defindo // mude a variavel bconexao para escolher o banco de dados // importe os drivers para o projeto // oracle = ORACLE // db2 = IBM DB2 // mssql = MSSQL Server bconexao = "mssql"; acesso.conectar(bconexao); formulario.setContentPane(acesso.criaPainel()); // Exibe o formulario formulario.setSize(400, 450); formulario.setVisible(true); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // Mostra GUI criaGUI(); } }); } }