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

View - CSharp

View – CSharp

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 ViewTrigger 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.

Visual Studio

Você encontra um walkthrough de como instalar os bancos de dados, seus drivers e a configuração da IDE Visual Studio na categoria SQL e C#, use a imagem abaixo para referencia de como criar design utilizando, 3 Panels, 8 Labels, 7 TextBox e 5 Buttons:

Visual Studio - Design

Visual Studio – Design

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 C# 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 C# 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;

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using Oracle.DataAccess.Client;
using IBM.Data.DB2;

namespace DACampos
{

    public partial class Campos : Form
    {
        // Declara componentes de conexão
        private static OracleConnection connORA; // ODAC 12c
        private static DB2Connection connDB2;   // IBM Data Server Provider
        private static SqlConnection connMSSQL; // ADO .NET

       // ************** Sobre Conexões - ADO.NET ************** 
       // 
       // A Microsoft disponibiliza por exemplo, o System.Data.OracleClient
       // porem se tornou obsoleto e ainda é suportado somente
       // a nível de compatibilidade com versões anteriores do Framework.
       // A Microsoft recomenda utilizar o driver de cada fornecedor:
       //
       // veja: http://msdn.microsoft.com/en-us/library/77d8yct7.aspx
       // 
       // Você pode utilizar a classe DbProviderFactory
       // para criar um único datasource para todos os bancos de dados: 
       //
       // http://msdn.microsoft.com/pt-br/library/system.data.common.dbproviderfactory(v=vs.110).aspx
       //
       // No entanto diferentemente da linguagem JAVA (JDBC) o ADO.NET não suporta
       // alguns recursos do Oracle e IBM DB2.    
       //
       // *** Factory ***
       //
       // Utilizando conexões únicas de cada provedor de banco de dados
       // através de um Factory, permite que você utilize um único set de instruções 
       // para todos os bancos de dados.
       //
       // Atente-se que se utilizar instruções únicas, em alguns casos poderá encontrar
       // alguns erros de compatibilidade ou criar certas limitações a outros bancos. 
       // O ADO.NET é desenvolvido para o MSSQL Server e está sujeito 
       // a algumas limitações quando utilizar alguns tipos de campos, 
       // conceitos de conexão e acesso a dados de outros bancos de dados.
       //
       // Sistemas de grande porte possuem um Dicionário de dados
       // para se prevenir destas situações.
       // 
       // Veja este mesmo programa utilizando o DriverManager equivalente ao factory para java
       // e veja comentários extras no código apontando diferenças de conceitos.
      

        // Declara variável do banco de dados
        private static string DBconexao;

        public Campos()
        {
            InitializeComponent();
        }

        // Cria método de conexão
        public void conectarDB(string banco)
        {
            DBconexao = banco;

            if (banco == "oracle")
            {

                try
                {
                    // String de Conexao
                    string connectionString =

                    // Usuario
                    "User Id=daberto"+

                    // Senha
                    ";Password=p@55w0rd" +

                    // TNSnames
                    ";Data Source=XE";

                    //Conecta ao datasource usando a conexão Oracle
                    connORA = new OracleConnection(connectionString);

                    //Abre a conexão com o banco de dados
                    connORA.Open();
                }
                    // Retorna erro
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());
                }
            }

            if (banco == "db2")
            {
                try
                {
                    // String de Conexao
                    string connectionString =

                        // Servidor
                        "Server=localhost" + 

                        // Banco de dados
                        ";Database=DEVA" +

                        // Usuario
                        ";UID=db2admin" + 

                        // Senha
                        ";PWD=p@55w0rd" + 

                        // Timeout
                        ";Connect Timeout=40";

                    //Conecta ao datasource usando a conexão DB2
                    connDB2 = new DB2Connection(connectionString);

                    //Abre a conexão com o banco de dados
                    connDB2.Open();

                }
                // Retorna erro
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());

                }

            }

            if (banco == "mssql")
            {
                try
                {
                    // String de Conexao
                    string connectionString =

                        // Servidor
                        "Data Source=localhost" + 

                        // Banco de dados
                        ";Initial Catalog=DevAberto" +

                        // Usuario
                        ";User ID =devaberto" + 

                        // Senha
                        ";Password=p@55w0rd" +

                        // Timeout
                        ";Connect Timeout=40";

                    //Conecta ao datasource usando a conexão Padrão
                    connMSSQL = new SqlConnection(connectionString);

                    //Abre a conexão com o banco de dados
                    connMSSQL.Open();

                }
                // Retorna erro
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());

                }

            }

        }

        // Evento de clique do botão
        private void button1_Click(object sender, EventArgs e)
        {
            // Cria instancia do objeto
            Campos campos = new Campos();

            // A variável abaixo:
            // Define banco de dados
            // oracle = Oracle Database
            // db2    = IBM DB2 Database
            // mssql  = Microsoft SQL Server
            campos.conectarDB("oracle");

            // Define instrução SQL
            // Seleciona dados da View
            string sql = "Select * From CadFuncionario Where  ID_FUNCIONARIO = " + textBox6.Text;

            // Usando um procedimento de conexão para da driver especifico

            // Oracle - ODAC
            if (DBconexao == "oracle")
            {
                label1.Text = "Database - Cadastro Funcionários: " + DBconexao;

                OracleCommand oracmd = new OracleCommand(sql, connORA);
                OracleDataReader orareader = oracmd.ExecuteReader();

                if (orareader.HasRows)
                {
                    while (orareader.Read())
                    {
                        textBox1.Text = Convert.ToString(orareader.GetInt32(0));
                        textBox2.Text = orareader.GetString(1);
                        textBox3.Text = orareader.GetString(2);
                        textBox4.Text = orareader.GetString(3);
                        textBox5.Text = Convert.ToString(orareader.GetDecimal(4));
                        textBox7.Text = Convert.ToString(orareader.GetDecimal(5));
                    }
                }

            }

            // IBM Data Server Provider
            if (DBconexao == "db2")
            {
                label1.Text = "Database - Cadastro Funcionários: " + DBconexao;

                DB2Command db2cmd = new DB2Command(sql);
                db2cmd.Connection = connDB2;
                DB2DataReader db2reader = db2cmd.ExecuteReader();

                if (db2reader.HasRows)
                {
                    while(db2reader.Read())
                    {
                        textBox1.Text = Convert.ToString(db2reader.GetInt32(0));
                        textBox2.Text = db2reader.GetString(1);
                        textBox3.Text = db2reader.GetString(2);
                        textBox4.Text = db2reader.GetString(3);
                        textBox5.Text = Convert.ToString(db2reader.GetDecimal(4));
                        textBox7.Text = Convert.ToString(db2reader.GetDecimal(5));
                    }
                }

            }

            // microsoft ADO.NET
           if (DBconexao == "mssql")
           {
               label1.Text = "Database - Cadastro Funcionários: " + DBconexao;

               SqlCommand mssqlcmd = new SqlCommand(sql);
               mssqlcmd.Connection = connMSSQL;
               SqlDataReader mssqlreader = mssqlcmd.ExecuteReader();

               if (mssqlreader.HasRows)
               {
                   while (mssqlreader.Read())
                   {
                       textBox1.Text = Convert.ToString(mssqlreader.GetInt32(0));
                       textBox2.Text = mssqlreader.GetString(1);
                       textBox3.Text = mssqlreader.GetString(2);
                       textBox4.Text = mssqlreader.GetString(3);
                       textBox5.Text = Convert.ToString(mssqlreader.GetDecimal(4));
                       textBox7.Text = Convert.ToString(mssqlreader.GetDecimal(5));
                   }
               }

               // Aqui nota-se uma diferença entre os drivers
               // Microsoft, Oracle e IBM
               // ADO.NET É necessário fechar o DataReader antes de executar um sqlcommand.
               // ODAC não é necessário
               // IBM DATA Server não é necessário
               // 
               // Aplica-se a qualquer DataReader ADO.NET
               //
               // Enquanto o DataReader está em uso, 
               // o Connection associado está ocupado servindo o DataReader.
               // Enquanto estiver neste estado, 
               // nenhuma outra operação pode ser realizada sobre o Connection além de fechá-lo.
               // Os drivers da Oracle e IBM não possuem esta arquitetura e não ocupam a conexão
               // permitindo ainda múltiplas operações sobre ela.


               mssqlreader.Close();
           }
        }

        private static void executaSQL(string sql)
        {
            // Declara comandos em diferentes drivers
            OracleCommand oracmd;
            DB2Command db2cmd;
            SqlCommand sqlcmd;

            // Define banco de dados e executa comandos SQL
            if (DBconexao == "oracle")
            {
                oracmd = new OracleCommand();
                oracmd.Connection = connORA;
                oracmd.CommandText = sql;

                try
                {
                    oracmd.ExecuteNonQuery();
                    MessageBox.Show("Ação requerida executada com sucesso!");
                }
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());
                }

            }

            if (DBconexao == "db2")
            {
                db2cmd = new DB2Command();
                db2cmd.Connection = connDB2;
                db2cmd.CommandText = sql;
                try
                {
                    db2cmd.ExecuteNonQuery();
                    MessageBox.Show("Ação requerida executada com sucesso!");
                }
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());
                }
            }

            if (DBconexao == "mssql")
            {
                sqlcmd = new SqlCommand();
                sqlcmd.Connection = connMSSQL;
                sqlcmd.CommandText = sql;

                try
                {
                    sqlcmd.ExecuteNonQuery();
                    MessageBox.Show("Ação requerida executada com sucesso!");
                }
                catch (Exception ex)
                {
                    // Mostra menssagem de erro
                    MessageBox.Show(ex.ToString());
                }
            }           

        }

        private static String trocaDecimal(string conteudo)
        {
            // Substitui decimal na manipulação de SQL
            string troca = conteudo.Replace(",", ".");
            return troca;
        }

        // Novo registro
        private void button2_Click(object sender, EventArgs e)
        {
            // Limpa componentes
            textBox1.Text = null;
            textBox2.Text = null;
            textBox3.Text = null;
            textBox4.Text = null;
            textBox5.Text = null;
            textBox7.Text = null;

            // Define foco
            textBox1.Focus();
        }

        // Insere registro
        private void button3_Click(object sender, EventArgs e)
        {
            // Cria instrução SQL
            string sql = "Insert into CadFuncionario values (" +
                textBox1.Text + ", \'" +
                textBox2.Text + "\', \'" +
                textBox3.Text + "\', \'" +
                textBox4.Text + "\', " +
                trocaDecimal(textBox5.Text) + ", " +
                trocaDecimal(textBox7.Text) + ")";

            // Executa sql
            executaSQL(sql);
        }

        // Altera registro
        private void button4_Click(object sender, EventArgs e)
        {
             // TODO: Criar uma Trigger como evento INSTEAD OF UPDATE
        }

        // Deleta registro
        private void button5_Click(object sender, EventArgs e)
        {
            // TODO: Criar uma Trigger como evento INSTEAD OF DELETE
        }
    }
}

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

View - Cadastro - Java

View – Cadastro – Java

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 ViewTrigger 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:

Drivers - External Jars

Eclipse – Drivers – External Jars

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();

            }
        });

    }

}

Ruby – Data Type – Array – Linux

Publicado: 11 de agosto de 2014 em Ruby on Rails

Como sabemos Ruby é uma linguagem de programação puramente orientada a objeto, então um Array em Ruby é um objeto pertencente a classe Array. A matriz é muito parecida com um objeto da classe Hash, entretanto um objeto Array é uma coleção indexada por números inteiros.

Um Array é um objeto muito rico em recursos por este motivo é recomendado utilizar os links oficias para saber mais detalhes sobre este objeto: Classe Array.

Ruby - Array

Ruby – Array

Exemplo:

Neste exemplo utilizamos o objeto da classe Array e alguns de seus métodos.

Ruby

#!/usr/bin/env ruby
# Desenvolvimento Aberto
# Arrays.rb

# Declara um array
matriz = ["Nirvana", "Alice in Chains", "Pearl Jam", "Screaming Trees"]

# Imprime o Array
matriz.each do |conteudo|
  puts conteudo
end

puts "\nDeleta um item do array"
matriz.delete("Pearl Jam")
matriz.each do |conteudo|
  puts conteudo
end

puts "\nRetira o ultimo elemento da array"
matriz.pop
matriz.each do |conteudo|
  puts conteudo
end

puts "\nInclui um item ao array"
matriz << "MudHoney"
matriz.each do |conteudo|
  puts conteudo
end

Como sabemos o servidor de apresentação do sistema SAP, possui varias funções que permitem comunicação com o servidor de aplicações, como por exemplo, importar e exportar arquivos do lado cliente, entre suas varias outras funções, o servidor de apresentação nos permite também executar programas externos.

WS_EXECUTE é um módulo de função padrão disponível nos sistemas R/3 da SAP, dependendo da versão e nível de release. Esta função é responsável por executar qualquer programa não SAP, por exemplo, um editor, uma calculadora ou qualquer outro programa de sua escolha. WS_EXECUTE executa um programa no servidor de apresentação, podendo também utilizar parâmetros comuns para se comunicar com o executável.

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função WS_EXECUTE é uma delas, você pode substituir esta função pela classe CL_GUI_FRONTEND_SERVICES.

Abaixo vamos criar um programa baseado na brincadeira Simon disse, neste caso nosso programa passara mensagens através de parâmetros para um executável criado em uma outra linguagem de programação, o executável receberá a mensagem e a exibira em seu formulário.

Para a versão mais recente deste procedimento utilize CL_GUI_FRONTEND_SERVICES: Serviços de Frontend SAP

 

Comunicando-se com um programa C# através de parâmetros

1 – Primeiro precisamos criar um programa C# utilizando a IDE Visual Studio. Arraste para o formulário dois componentes Label, um componente PictureBox, 2 Componentes Panel e um componente Richtextbox. A captura dos parâmetros será executada no evento SHOWN do formulário. Utilize a figura abaixo para modelar o design do seu programa:

Visual Studio - Design

Visual Studio – Design

2 – Crie um novo programa Abap e utilize o código abaixo. Entre com um ou mais parâmetros separados por espaço na caixa de texto do sistema SAP e pressione o botão executar na barra de tarefas. Dê permissão para o servidor de apresentação executar o programa:

Parâmetros - Abap

Parâmetros – Abap

3 – Você receberá uma mensagem de acordo com o resultado apresentado pelo servidor de apresentação:

Resultado

Resultado

4 – Pronto o programa C# será executado e receberá os parâmetros enviados que serão mostrados em uma caixa de texto. Visto que o ambiente do .NET Framework nos retorna um ARRAY contendo, primeiro o caminho e o nome do executável e sequencialmente todos os parâmetros enviados:

Programa C# - Parâmetros

Programa C# – Parâmetros

Exemplo:

Neste exemplo escrevemos dois programas em linguagens de programação diferentes e conseguimos uma comunicação entre eles por meio de parâmetros, este simples exemplo nos mostra inúmeras possibilidades de comunicação entre um programa ABAP e programas externos sem utilizar as funções de RFC da SAP.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CsSap
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            // Recupera e exibi parâmetros enviados para o executavel
            string[] args = Environment.GetCommandLineArgs();
            richTextBox1.AppendText(string.Format("{0}", String.Join(", ", args)));      
           
            // TODO: Criar funcionalidades para os parâmetros recebidos.
        }

    }
}

Abap

Função WS_EXECUTE:

*&---------------------------------------------------------------------*
*& Report  ZSAPDISSE
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& SAP Disse: WS_EXECUTE
*&---------------------------------------------------------------------*

REPORT  ZSAPDISSE.

* cria parametro para os parametros do executavel
PARAMETER SAPDISSE TYPE c LENGTH 70.

* declara variavel para o caminho do executavel
DATA programa TYPE string.

programa = 'C:\Desenvolvimento Aberto\temp\CsSap.exe'.

* Chama função que executa um executavel
CALL FUNCTION 'WS_EXECUTE'
  EXPORTING
    PROGRAM            = programa
    COMMANDLINE        = SAPDISSE
    INFORM             = ' '
  EXCEPTIONS
    FRONTEND_ERROR     = 1
    NO_BATCH           = 2
    PROG_NOT_FOUND     = 3
    ILLEGAL_OPTION     = 4
    GUI_REFUSE_EXECUTE = 5
    OTHERS             = 6.

* verifica estado da execução
CASE SY-SUBRC.
  WHEN 1.
    WRITE: / 'ERRO NO FRONTEND!'.
  WHEN 2.
    WRITE: / 'NO BATCH!'.
  WHEN 3.
    WRITE: / 'PROGRAMA NÃO ECONTRADO!'.
  WHEN 4.
    WRITE: / 'OPÇÃO ILEGAL!'.
  WHEN 5.
    WRITE: / 'SAP GUI SE RECUSOU A EXECUTAR O PROGRAMA!'.
  WHEN 6.
    WRITE: / 'OUTROS ERROS!'.
  WHEN OTHERS.
    WRITE: / 'PROGRAMA EXECUTADO COM SUCESSO!!!!'.
    MESSAGE 'Programa executado com sucesso!' TYPE 'S'.
ENDCASE.

Classe CL_GUI_FRONTEND_SERVICES:

*&---------------------------------------------------------------------*
*& Report  ZSAPDISSE_FES
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& CL_GUI_FRONTEND_SERVICES
*&---------------------------------------------------------------------*

REPORT  ZSAPDISSE_FES.

* cria parametro para os parametros do executavel
PARAMETER SAPDISSE TYPE string.

* declara variavel para o caminho do executavel
DATA programa TYPE string.

programa = 'C:\Desenvolvimento Aberto\temp\CsSap.exe'.

* Executa método de classe
CL_GUI_FRONTEND_SERVICES=>EXECUTE(
  exporting
    APPLICATION            =     programa
    PARAMETER              =     sapdisse
  exceptions
    CNTL_ERROR             = 1
    ERROR_NO_GUI           = 2
    BAD_PARAMETER          = 3
    FILE_NOT_FOUND         = 4
    PATH_NOT_FOUND         = 5
    FILE_EXTENSION_UNKNOWN = 6
    ERROR_EXECUTE_FAILED   = 7
    SYNCHRONOUS_FAILED     = 8
    NOT_SUPPORTED_BY_GUI   = 9
    OTHERS                 = 10 ).

* verifica estado da execução
CASE SY-SUBRC.
  WHEN 1.
    WRITE: / 'ERRO CNTL!'.
  WHEN 2.
    WRITE: / 'ERRO NO FRONTEND!!'.
  WHEN 3.
    WRITE: / 'ERRO NO PARAMETRO!'.
  WHEN 4.
    WRITE: / 'PROGRAMA NÃO ECONTRADO!'.
  WHEN 5.
    WRITE: / 'CAMINHO NÃO ECONTRADO!'.
  WHEN 6.
    WRITE: / 'EXTENSÃO DESCONHECIDA!'.
  WHEN 7.
    WRITE: / 'ERRO DE EXECUÇÃO!'.
  WHEN 8.
    WRITE: / 'FALHA NA SINCRONIZAÇÃO!'.
  WHEN 9.
    WRITE: / 'NÃO SUPORTADO PELO GUI!'.
  WHEN 10.
    WRITE: / 'OUTROS!'.
  WHEN OTHERS.
    WRITE: / 'PROGRAMA EXECUTADO COM SUCESSO!!!!'.
    MESSAGE 'Programa executado com sucesso!' TYPE 'S'.
ENDCASE.

 

Para ler dados a partir do servidor de apresentação para uma tabela interna usando um diálogo de usuário, use a função de Upload. Para ler dados a partir do servidor de apresentação para uma tabela interna sem o uso de uma caixa de diálogo do usuário, use a função WS_UPLOAD. Para mais informações, consulte a documentação do módulo de função (SE37).

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função Upload é uma delas, você pode substituir esta função pela função chamada GUI_UPLOAD.

GUI_UPLOAD: Função GUI_UPLOAD

Importando arquivo do Excel para uma tabela interna

1 – Para utilizar este exemplo, primeiro crie uma planilha comum com três colunas do tipo xls:

Open Office Calc

Open Office Calc

2 – Exporte a planilha para um arquivo texto separado por tabulações:

Texto - separados por tab

Texto – separados por tab

3 – Utilize o código abaixo para importar o arquivo para uma tabela interna:

Tabela Interna

Tabela Interna

 

Exemplo:

Neste exemplo importamos dados de um arquivo texto separado por tabs de uma planilha no formato xls.

Abap

Function : UPLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER3
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Servidor de Apresentação - Upload
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER3.

* Declara variaveis
DATA: FNOME(128), FTIPO(3), FTAMANHO TYPE I.

* Cria tabela
TYPES: BEGIN OF LINE,
  COL1(10) TYPE C,
  COL2(10) TYPE C,
  COL3(20) TYPE C,
END OF LINE.

* Cria e declara tabela interna
TYPES ITAB TYPE LINE OCCURS 10.
DATA: LIN TYPE LINE,
TAB TYPE ITAB.

* Chama a função de Upload
CALL FUNCTION 'UPLOAD'
  EXPORTING
    CODEPAGE            = 'IBM'
    FILENAME            = 'C:\Desenvolvimento Aberto\temp\Plan001.txt'
    FILETYPE            = 'DAT'
    ITEM                = 'Lê arquivo txt separado por tab exportado do Excel'
  IMPORTING
    FILESIZE            = FTAMANHO
    ACT_FILENAME        = FNOME
    ACT_FILETYPE        = FTIPO
  TABLES
    DATA_TAB            = TAB
  EXCEPTIONS
    CONVERSION_ERROR    = 1
    INVALID_TABLE_WIDTH = 2
    INVALID_TYPE        = 3.

* Imprime dados na tela
WRITE: 'SY-SUBRC:', SY-SUBRC,
/ 'Name :', (60) FNOME,
/ 'Type :', FTIPO,
/ 'Size :', FTAMANHO.

SKIP 2.

WRITE / 'Conteudo do Arquivo .TXT:'.

SKIP.

LOOP AT TAB INTO LIN.
  WRITE: / LIN-COL1, LIN-COL2 COLOR 4 INVERSE, LIN-COL3 COLOR 3 INVERSE.
ENDLOOP.

Function : GUI_UPLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER4
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& GUI_UPLOAD
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER4.

* Declara variaveis
DATA: FTAMANHO TYPE I.

* Cria tabela
TYPES: BEGIN OF LINE,
  COL1(10) TYPE C,
  COL2(10) TYPE C,
  COL3(20) TYPE C,
END OF LINE.

* Cria e declara tabela interna
TYPES ITAB TYPE LINE OCCURS 10.
DATA: LIN TYPE LINE,
TAB TYPE ITAB.

* Chama função GUI_UPLOAD
CALL FUNCTION 'GUI_UPLOAD'
  exporting
    FILENAME                = 'C:\Desenvolvimento Aberto\temp\Plan001.txt'
    FILETYPE                = 'DAT'
  importing
    FILELENGTH              = FTAMANHO
  tables
    DATA_TAB                = TAB
  exceptions
    FILE_OPEN_ERROR         = 1
    FILE_READ_ERROR         = 2
    INVALID_TYPE            = 3.

* Imprime dados na tela
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Size :', FTAMANHO.

SKIP 2.

WRITE / 'Conteudo do Arquivo .TXT:'.

SKIP.

LOOP AT TAB INTO LIN.
  WRITE: / LIN-COL1, LIN-COL2 COLOR 4 INVERSE, LIN-COL3 COLOR 3 INVERSE.
ENDLOOP.

Para gravar dados a partir de uma tabela interna para o servidor de apresentação usando um diálogo de usuário, use a função de Download. Para gravar dados de uma tabela interna para o servidor de apresentação sem o uso de uma caixa de diálogo do usuário, use a função WS_DOWNLOAD. Para mais informações, consulte a documentação do módulo de função (SE37).

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função Download é uma delas, você pode substituir esta função pela função chamada GUI_DOWNLOAD.

Exporta para XLS

Exporta para XLS

GUI_DOWNLOAD: http://help.sap.com/saphelp_nw70ehp2/helpdata/de/c7/5ab8ec178c44a8aacd1dcac3460db8/content.htm

Exemplo:

Neste exemplo extraímos dados de uma tabela interna em um arquivo Excel e o salvamos no computador local.

Abap

Function : DOWNLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Escreve dados no servidor de apresentação
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER.

* Declara Variáveis
DATA: FNOME(128), FTIPO(3), FTAMANHO TYPE I.

* Cria tabela com duas colunas
TYPES: BEGIN OF LINE,
  COL1 TYPE I,
  COL2 TYPE I,
END OF LINE.

* Cria Tabela temporaria
TYPES ITAB TYPE LINE OCCURS 15.
DATA: LIN  TYPE LINE, TAB TYPE ITAB.

* Cria e adiciona dados a tabela
DO 15 TIMES.
  LIN-COL1 = SY-INDEX.
  LIN-COL2 = SY-INDEX ** 2.
  APPEND LIN TO TAB.
ENDDO.

* Chama a função de download
* Dat cria tipo do Excel
CALL FUNCTION 'DOWNLOAD'
  EXPORTING
    CODEPAGE            = 'IBM'
    FILENAME            = 'C:\Desenvolvimento Aberto\temp\Planilha.xls'
    FILETYPE            = 'DAT'
    ITEM                = 'Teste Excel'
  IMPORTING
    ACT_FILENAME        = FNOME
    ACT_FILETYPE        = FTIPO
    FILESIZE            = FTAMANHO
  TABLES
    DATA_TAB            = TAB
  EXCEPTIONS
    INVALID_FILESIZE    = 1
    INVALID_TABLE_WIDTH = 2
    INVALID_TYPE        = 3.

* Imprime resultado
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Nome :', (60) FNOME,
     / 'Tipo :', FTIPO,
     / 'Tamanho :', FTAMANHO.

WRITE : / 'Conteudo do arquivo:', /.
LOOP AT tab INTO lin.
   WRITE : / LIN-COL1 COLOR 3 INVERSE,
             LIN-COL2 COLOR 3 INVERSE.
ENDLOOP.

Function : GUI_DOWNLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER2
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& GUI_DOWNLOAD
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER2.
* Declara Variáveis
DATA:  FTAMANHO TYPE I.

* Cria tabela com duas colunas
TYPES: BEGIN OF LINE,
  COL1 TYPE I,
  COL2 TYPE I,
END OF LINE.

* Cria Tabela temporaria
TYPES ITAB TYPE LINE OCCURS 15.
DATA: LIN  TYPE LINE, TAB TYPE ITAB.

* Cria e adiciona dados a tabela
DO 15 TIMES.
  LIN-COL1 = SY-INDEX.
  LIN-COL2 = SY-INDEX ** 2.
  APPEND LIN TO TAB.
ENDDO.

* Chama a função de download
* Dat cria tipo do Excel
CALL FUNCTION 'GUI_DOWNLOAD'
  EXPORTING
    FILENAME   = 'C:\Desenvolvimento Aberto\temp\Planilha2.xls'
    FILETYPE   = 'DAT'
  IMPORTING
    FILELENGTH = FTAMANHO
  TABLES
    DATA_TAB   = TAB.

* Imprime resultado
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Tamanho :', FTAMANHO.

WRITE : / 'Conteudo do arquivo:', /.
LOOP AT tab INTO lin.
  WRITE : / LIN-COL1 COLOR 3 INVERSE,
            LIN-COL2 COLOR 3 INVERSE.
ENDLOOP.

Wget – Como Clonar Sites – C – Linux

Publicado: 7 de agosto de 2014 em Hacking

Você sabe que o mundo da internet é recheado de perigos e os mais comuns são os vírus, worms, malwares e cavalos de troia, estes são pequenos programas criados para causar algum dano ao computador, seja apagando dados, capturando informações ou alterando o funcionamento normal da máquina. Com o combate intensivo a estas enfermidades, as empresas de antivírus atualizam constantemente nossos computadores com vacinas e proteções contra estas pragas virtuais, sendo assim desenvolvedores mal intencionados encontram outras formas, muitas vezes até mais simples para conseguir enganar e prejudicar o usuário final, e nem sempre o perigo vem da construção de complexos códigos e programas mirabolantes, e a forma mais fácil de roubar dados de um usuário é fazer com que o próprio usuário os entregue.

Cuidado com seus dados pessoais

Por este motivo tenha cuidado ao alimentar dados pessoais, mesmo em sites conhecidos, pois agora você vai aprender como é fácil cair em uma armadilha que pode custar muito caro. Se você é um aficionado por tecnologia e gosta de saber como as coisas são feitas realmente, você pode simular a clonagem de um site no seu computador.

Vamos criar um clone em um servidor web padrão instalado em nosso sistema operacional. Tudo que precisamos é um sistema operacional Linux padrão, um servidor web, e conhecimento básico na linguagem de scripts HTML. Isso! e nada mais!

WGet

GNU Wget é um programa livre, de fonte aberto, escrito com a poderosa linguagem de programação que propicia o download de dados da web. É parte do projeto GNU. Seu nome deriva de World Wide Web e get. Ele suporta os protocolos HTTP, HTTPS e FTP. A instalação padrão do Ubuntu já contempla este programa. O Wget possui vários parâmetros e você pode efetuar downloads específicos ou até mesmo de sites inteiros. Na verdade este programa é muito útil, porem pode ser usado por usuários mal intencionados para clonar sites.

Pagina oficial: https://www.gnu.org/software/wget/

Manual: Wget Manual

 

Como Clonar Um Site

1 – Primeiro você precisa de um servidor web instalado em seu computador, você pode usar o servidor gratuito Apache2, caso você queira saber como instalar e configurar o servidor Apache em Linux, clique aqui.

Site Windows - Original

Site Windows – Original

 

2 – Faremos um teste na pagina oficial do Windows 8. Após instalar e configurar o Apache, crie uma pasta qualquer no diretório de sua preferencia, abra o terminal do Linux na pasta que você criou e digite o seguinte comando:


wget -S http://windows.microsoft.com/pt-br/windows/home

Wget - Terminal

Wget – Terminal

 

3 – Após o download você pode renomear a pagina baixada para index.html e modifica-la como bem entender no editor de sua preferencia, caso queira usar o padrão Linux, use o GEdit. Copie o arquivo baixado e modificado para o diretório www do Apache, abra o browser e digite localhost:

Site - Windows - Clonado - Localhost

Site – Windows – Clonado – Localhost

 

Pronto! Como você pode ver localhost é o servidor web do computador local, um servidor web como qualquer outro onde os sites são hospedados, geralmente desenvolvedores mal intencionados utilizam um domínio muito parecido com o domínio utilizado pelo site que foi clonado, tentando enganar os usuários mais desatentos, estes sites são hospedados em servidores web de outros países dificultando assim sua completa identificação.

Quase sempre estes sites coletam informações pessoais como numero de cartão de crédito, senhas, contas bancarias e outros dados relevantes que possam causar algum tipo de prejuízo ao usuário dos sites originais, outras vezes estes sites servem apenas para contaminar o computador do usuário com vírus ou outros tipo softwares que podem resultar em controle total do computador. Assim que seu objetivo é alcançado estes sites simplesmente desaparecem.

 

Exemplo:

Neste exemplo utilizamos o programa wget pré-instalado no Linux para clonar a pagina índice do site do Windows, modificamos o HTML da pagina e a colamos em um servidor web de testes no computador local. Visto que a pagina clonada possui os links originais e é totalmente utilizável.

Caso você queira aprender como funciona este programa você pode baixar o código fonte deste link:
Wget source code: http://ftp.gnu.org/gnu/wget/

C

Use o código abaixo para conhecer os parâmetros disponibilizados pelo programa wget de um ponto de vista do desenvolvedor.

Main.c

/* Command line parsing.
   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.

This file is part of Wget.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <sys/types.h>
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#ifdef HAVE_NLS
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif /* HAVE_LOCALE_H */
#endif /* HAVE_NLS */

#define OPTIONS_DEFINED_HERE	/* for options.h */

#include "wget.h"
#include "utils.h"
#include "getopt.h"
#include "init.h"
#include "retr.h"
#include "recur.h"
#include "host.h"

#ifndef PATH_SEPARATOR
# define PATH_SEPARATOR '/'
#endif

extern char *version_string;

#ifndef errno
extern int errno;
#endif

struct options opt;

/* From log.c.  */
void log_init PARAMS ((const char *, int));
void log_close PARAMS ((void));
void redirect_output PARAMS ((const char *));

static RETSIGTYPE redirect_output_signal PARAMS ((int));

const char *exec_name;

/* Initialize I18N.  The initialization amounts to invoking
   setlocale(), bindtextdomain() and textdomain().
   Does nothing if NLS is disabled or missing.  */
static void
i18n_initialize (void)
{
  /* If HAVE_NLS is defined, assume the existence of the three
     functions invoked here.  */
#ifdef HAVE_NLS
  /* Set the current locale.  */
  /* Here we use LC_MESSAGES instead of LC_ALL, for two reasons.
     First, message catalogs are all of I18N Wget uses anyway.
     Second, setting LC_ALL has a dangerous potential of messing
     things up.  For example, when in a foreign locale, Solaris
     strptime() fails to handle international dates correctly, which
     makes http_atotm() malfunction.  */
  setlocale (LC_MESSAGES, "");
  /* Set the text message domain.  */
  bindtextdomain ("wget", LOCALEDIR);
  textdomain ("wget");
#endif /* HAVE_NLS */
}

/* Print the usage message.  */
static void
print_usage (void)
{
  printf (_("Usage: %s [OPTION]... [URL]...\n"), exec_name);
}

/* Print the help message, describing all the available options.  If
   you add an option, be sure to update this list.  */
static void
print_help (void)
{
  printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
	  version_string);
  print_usage ();
  /* Had to split this in parts, so the #@@#%# Ultrix compiler and cpp
     don't bitch.  Also, it makes translation much easier.  */
  printf ("%s%s%s%s%s%s%s%s%s%s", _("\
\n\
Mandatory arguments to long options are mandatory for short options too.\n\
\n"), _("\
Startup:\n\
  -V,  --version           display the version of Wget and exit.\n\
  -h,  --help              print this help.\n\
  -b,  --background        go to background after startup.\n\
  -e,  --execute=COMMAND   execute a `.wgetrc\' command.\n\
\n"), _("\
Logging and input file:\n\
  -o,  --output-file=FILE     log messages to FILE.\n\
  -a,  --append-output=FILE   append messages to FILE.\n\
  -d,  --debug                print debug output.\n\
  -q,  --quiet                quiet (no output).\n\
  -v,  --verbose              be verbose (this is the default).\n\
  -nv, --non-verbose          turn off verboseness, without being quiet.\n\
  -i,  --input-file=FILE      read URL-s from file.\n\
  -F,  --force-html           treat input file as HTML.\n\
\n"), _("\
Download:\n\
  -t,  --tries=NUMBER           set number of retries to NUMBER (0 unlimits).\n\
  -O   --output-document=FILE   write documents to FILE.\n\
  -nc, --no-clobber             don\'t clobber existing files.\n\
  -c,  --continue               restart getting an existing file.\n\
       --dot-style=STYLE        set retrieval display style.\n\
  -N,  --timestamping           don\'t retrieve files if older than local.\n\
  -S,  --server-response        print server response.\n\
       --spider                 don\'t download anything.\n\
  -T,  --timeout=SECONDS        set the read timeout to SECONDS.\n\
  -w,  --wait=SECONDS           wait SECONDS between retrievals.\n\
  -Y,  --proxy=on/off           turn proxy on or off.\n\
  -Q,  --quota=NUMBER           set retrieval quota to NUMBER.\n\
\n"),  _("\
Directories:\n\
  -nd  --no-directories            don\'t create directories.\n\
  -x,  --force-directories         force creation of directories.\n\
  -nH, --no-host-directories       don\'t create host directories.\n\
  -P,  --directory-prefix=PREFIX   save files to PREFIX/...\n\
       --cut-dirs=NUMBER           ignore NUMBER remote directory components.\n\
\n"), _("\
HTTP options:\n\
       --http-user=USER      set http user to USER.\n\
       --http-passwd=PASS    set http password to PASS.\n\
  -C,  --cache=on/off        (dis)allow server-cached data (normally allowed).\n\
       --ignore-length       ignore `Content-Length\' header field.\n\
       --header=STRING       insert STRING among the headers.\n\
       --proxy-user=USER     set USER as proxy username.\n\
       --proxy-passwd=PASS   set PASS as proxy password.\n\
  -s,  --save-headers        save the HTTP headers to file.\n\
  -U,  --user-agent=AGENT    identify as AGENT instead of Wget/VERSION.\n\
\n"), _("\
FTP options:\n\
       --retr-symlinks   retrieve FTP symbolic links.\n\
  -g,  --glob=on/off     turn file name globbing on or off.\n\
       --passive-ftp     use the \"passive\" transfer mode.\n\
\n"), _("\
Recursive retrieval:\n\
  -r,  --recursive             recursive web-suck -- use with care!.\n\
  -l,  --level=NUMBER          maximum recursion depth (0 to unlimit).\n\
       --delete-after          delete downloaded files.\n\
  -k,  --convert-links         convert non-relative links to relative.\n\
  -m,  --mirror                turn on options suitable for mirroring.\n\
  -nr, --dont-remove-listing   don\'t remove `.listing\' files.\n\
\n"), _("\
Recursive accept/reject:\n\
  -A,  --accept=LIST                list of accepted extensions.\n\
  -R,  --reject=LIST                list of rejected extensions.\n\
  -D,  --domains=LIST               list of accepted domains.\n\
       --exclude-domains=LIST       comma-separated list of rejected domains.\n\
  -L,  --relative                   follow relative links only.\n\
       --follow-ftp                 follow FTP links from HTML documents.\n\
  -H,  --span-hosts                 go to foreign hosts when recursive.\n\
  -I,  --include-directories=LIST   list of allowed directories.\n\
  -X,  --exclude-directories=LIST   list of excluded directories.\n\
  -nh, --no-host-lookup             don\'t DNS-lookup hosts.\n\
  -np, --no-parent                  don\'t ascend to the parent directory.\n\
\n"), _("Mail bug reports and suggestions to <bug-wget@gnu.org>.\n"));
}

int
main (int argc, char *const *argv)
{
  char **url, **t;
  int i, c, nurl, status, append_to_log;

  static struct option long_options[] =
  {
    { "background", no_argument, NULL, 'b' },
    { "continue", no_argument, NULL, 'c' },
    { "convert-links", no_argument, NULL, 'k' },
    { "debug", no_argument, NULL, 'd' },
    { "dont-remove-listing", no_argument, NULL, 21 },
    { "email-address", no_argument, NULL, 'E' }, /* undocumented (debug) */
    { "follow-ftp", no_argument, NULL, 14 },
    { "force-directories", no_argument, NULL, 'x' },
    { "force-hier", no_argument, NULL, 'x' }, /* obsolete */
    { "force-html", no_argument, NULL, 'F'},
    { "help", no_argument, NULL, 'h' },
    { "ignore-length", no_argument, NULL, 10 },
    { "mirror", no_argument, NULL, 'm' },
    { "no-clobber", no_argument, NULL, 13 },
    { "no-directories", no_argument, NULL, 19 },
    { "no-host-directories", no_argument, NULL, 20 },
    { "no-host-lookup", no_argument, NULL, 22 },
    { "no-parent", no_argument, NULL, 5 },
    { "non-verbose", no_argument, NULL, 18 },
    { "passive-ftp", no_argument, NULL, 11 },
    { "quiet", no_argument, NULL, 'q' },
    { "recursive", no_argument, NULL, 'r' },
    { "relative", no_argument, NULL, 'L' },
    { "retr-symlinks", no_argument, NULL, 9 },
    { "save-headers", no_argument, NULL, 's' },
    { "server-response", no_argument, NULL, 'S' },
    { "span-hosts", no_argument, NULL, 'H' },
    { "spider", no_argument, NULL, 4 },
    { "timestamping", no_argument, NULL, 'N' },
    { "verbose", no_argument, NULL, 'v' },
    { "version", no_argument, NULL, 'V' },

    { "accept", required_argument, NULL, 'A' },
    { "append-output", required_argument, NULL, 'a' },
    { "backups", required_argument, NULL, 23 }, /* undocumented */
    { "base", required_argument, NULL, 'B' },
    { "cache", required_argument, NULL, 'C' },
    { "cut-dirs", required_argument, NULL, 17 },
    { "delete-after", no_argument, NULL, 8 },
    { "directory-prefix", required_argument, NULL, 'P' },
    { "domains", required_argument, NULL, 'D' },
    { "dot-style", required_argument, NULL, 6 },
    { "execute", required_argument, NULL, 'e' },
    { "exclude-directories", required_argument, NULL, 'X' },
    { "exclude-domains", required_argument, NULL, 12 },
    { "glob", required_argument, NULL, 'g' },
    { "header", required_argument, NULL, 3 },
    { "htmlify", required_argument, NULL, 7 },
    { "http-passwd", required_argument, NULL, 2 },
    { "http-user", required_argument, NULL, 1 },
    { "include-directories", required_argument, NULL, 'I' },
    { "input-file", required_argument, NULL, 'i' },
    { "level", required_argument, NULL, 'l' },
    { "no", required_argument, NULL, 'n' },
    { "output-document", required_argument, NULL, 'O' },
    { "output-file", required_argument, NULL, 'o' },
    { "proxy", required_argument, NULL, 'Y' },
    { "proxy-passwd", required_argument, NULL, 16 },
    { "proxy-user", required_argument, NULL, 15 },
    { "quota", required_argument, NULL, 'Q' },
    { "reject", required_argument, NULL, 'R' },
    { "timeout", required_argument, NULL, 'T' },
    { "tries", required_argument, NULL, 't' },
    { "user-agent", required_argument, NULL, 'U' },
    { "use-proxy", required_argument, NULL, 'Y' },
    { "wait", required_argument, NULL, 'w' },
    { 0, 0, 0, 0 }
  };

  i18n_initialize ();

  append_to_log = 0;

  /* Construct the name of the executable, without the directory part.  */
  exec_name = strrchr (argv[0], PATH_SEPARATOR);
  if (!exec_name)
    exec_name = argv[0];
  else
    ++exec_name;

#ifdef WINDOWS
  windows_main_junk (&argc, (char **) argv, (char **) &exec_name);
#endif

  initialize ();

  while ((c = getopt_long (argc, argv, "\
hVqvdksxmNWrHSLcFbEY:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:",
			   long_options, (int *)0)) != EOF)
    {
      switch (c)
	{
	  /* Options without arguments: */
	case 4:
	  setval ("spider", "on");
	  break;
	case 5:
	  setval ("noparent", "on");
	  break;
	case 8:
	  setval ("deleteafter", "on");
	  break;
	case 9:
	  setval ("retrsymlinks", "on");
	  break;
	case 10:
	  setval ("ignorelength", "on");
	  break;
	case 11:
	  setval ("passiveftp", "on");
	  break;
	case 13:
	  setval ("noclobber", "on");
	  break;
	case 14:
	  setval ("followftp", "on");
	  break;
	case 17:
	  setval ("cutdirs", optarg);
	  break;
	case 18:
	  setval ("verbose", "off");
	  break;
	case 19:
	  setval ("dirstruct", "off");
	  break;
	case 20:
	  setval ("addhostdir", "off");
	  break;
	case 21:
	  setval ("removelisting", "off");
	  break;
	case 22:
	  setval ("simplehostcheck", "on");
	  break;
	case 'b':
	  setval ("background", "on");
	  break;
	case 'c':
	  setval ("continue", "on");
	  break;
	case 'd':
#ifdef DEBUG
	  setval ("debug", "on");
#else  /* not DEBUG */
	  fprintf (stderr, _("%s: debug support not compiled in.\n"),
		   exec_name);
#endif /* not DEBUG */
	  break;
	case 'E':
	  /* For debugging purposes.  */
	  printf ("%s\n", ftp_getaddress ());
	  exit (0);
	  break;
	case 'F':
	  setval ("forcehtml", "on");
	  break;
	case 'H':
	  setval ("spanhosts", "on");
	  break;
	case 'h':
	  print_help ();
#ifdef WINDOWS
	  ws_help (exec_name);
#endif
	  exit (0);
	  break;
	case 'k':
	  setval ("convertlinks", "on");
	  break;
	case 'L':
	  setval ("relativeonly", "on");
	  break;
	case 'm':
	  setval ("mirror", "on");
	  break;
	case 'N':
	  setval ("timestamping", "on");
	  break;
	case 'S':
	  setval ("serverresponse", "on");
	  break;
	case 's':
	  setval ("saveheaders", "on");
	  break;
	case 'q':
	  setval ("quiet", "on");
	  break;
	case 'r':
	  setval ("recursive", "on");
	  break;
	case 'V':
	  printf ("GNU Wget %s\n\n", version_string);
	  printf ("%s", _("\
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\n\
This program is distributed in the hope that it will be useful,\n\
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
GNU General Public License for more details.\n"));
	  printf (_("\nWritten by Hrvoje Niksic <hniksic@srce.hr>.\n"));
	  exit (0);
	  break;
	case 'v':
	  setval ("verbose", "on");
	  break;
	case 'x':
	  setval ("dirstruct", "on");
	  break;

	  /* Options accepting an argument: */
	case 1:
	  setval ("httpuser", optarg);
	  break;
	case 2:
	  setval ("httppasswd", optarg);
	  break;
	case 3:
	  setval ("header", optarg);
	  break;
	case 6:
	  setval ("dotstyle", optarg);
	  break;
	case 7:
	  setval ("htmlify", optarg);
	  break;
	case 12:
	  setval ("excludedomains", optarg);
	  break;
	case 15:
	  setval ("proxyuser", optarg);
	  break;
	case 16:
	  setval ("proxypasswd", optarg);
	  break;
	case 23:
	  setval ("backups", optarg);
	  break;
	case 'A':
	  setval ("accept", optarg);
	  break;
	case 'a':
	  setval ("logfile", optarg);
	  append_to_log = 1;
	  break;
	case 'B':
	  setval ("base", optarg);
	  break;
	case 'C':
	  setval ("cache", optarg);
	  break;
	case 'D':
	  setval ("domains", optarg);
	  break;
	case 'e':
	  {
	    char *com, *val;
	    if (parse_line (optarg, &com, &val))
	      {
		if (!setval (com, val))
		  exit (1);
	      }
	    else
	      {
		fprintf (stderr, _("%s: %s: invalid command\n"), exec_name,
			 optarg);
		exit (1);
	      }
	    free (com);
	    free (val);
	  }
	  break;
	case 'g':
	  setval ("glob", optarg);
	  break;
	case 'I':
	  setval ("includedirectories", optarg);
	  break;
	case 'i':
	  setval ("input", optarg);
	  break;
	case 'l':
	  setval ("reclevel", optarg);
	  break;
	case 'n':
	  {
	    /* #### The n? options are utter crock!  */
	    char *p;

	    for (p = optarg; *p; p++)
	      switch (*p)
		{
		case 'v':
		  setval ("verbose", "off");
		  break;
		case 'h':
		  setval ("simplehostcheck", "on");
		  break;
		case 'H':
		  setval ("addhostdir", "off");
		  break;
		case 'd':
		  setval ("dirstruct", "off");
		  break;
		case 'c':
		  setval ("noclobber", "on");
		  break;
		case 'r':
		  setval ("removelisting", "off");
		  break;
		case 'p':
		  setval ("noparent", "on");
		  break;
		default:
		  printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p);
		  print_usage ();
		  printf ("\n");
		  printf (_("Try `%s --help\' for more options.\n"), exec_name);
		  exit (1);
		}
	    break;
	  }
	case 'O':
	  setval ("outputdocument", optarg);
	  break;
	case 'o':
	  setval ("logfile", optarg);
	  break;
	case 'P':
	  setval ("dirprefix", optarg);
	  break;
	case 'Q':
	  setval ("quota", optarg);
	  break;
	case 'R':
	  setval ("reject", optarg);
	  break;
	case 'T':
	  setval ("timeout", optarg);
	  break;
	case 't':
	  setval ("tries", optarg);
	  break;
	case 'U':
	  setval ("useragent", optarg);
	  break;
	case 'w':
	  setval ("wait", optarg);
	  break;
	case 'X':
	  setval ("excludedirectories", optarg);
	  break;
	case 'Y':
	  setval ("useproxy", optarg);
	  break;

	case '?':
	  print_usage ();
	  printf ("\n");
	  printf (_("Try `%s --help' for more options.\n"), exec_name);
	  exit (0);
	  break;
	}
    }
  if (opt.verbose == -1)
    opt.verbose = !opt.quiet;

  /* Sanity checks.  */
  if (opt.verbose && opt.quiet)
    {
      printf (_("Can't be verbose and quiet at the same time.\n"));
      print_usage ();
      exit (1);
    }
  if (opt.timestamping && opt.noclobber)
    {
      printf (_("\
Can't timestamp and not clobber old files at the same time.\n"));
      print_usage ();
      exit (1);
    }
  nurl = argc - optind;
  if (!nurl && !opt.input_filename)
    {
      /* No URL specified.  */
      printf (_("%s: missing URL\n"), exec_name);
      print_usage ();
      printf ("\n");
      /* #### Something nicer should be printed here -- similar to the
	 pre-1.5 `--help' page.  */
      printf (_("Try `%s --help' for more options.\n"), exec_name);
      exit (1);
    }

  if (opt.background)
    fork_to_background ();

  /* Allocate basic pointer.  */
  url = ALLOCA_ARRAY (char *, nurl + 1);
  /* Fill in the arguments.  */
  for (i = 0; i < nurl; i++, optind++)
    {
      char *irix4_cc_needs_this;
      STRDUP_ALLOCA (irix4_cc_needs_this, argv[optind]);
      url[i] = irix4_cc_needs_this;
    }
  url[i] = NULL;

  /* Change the title of console window on Windows.  #### I think this
     statement should belong to retrieve_url().  --hniksic.  */
#ifdef WINDOWS
  ws_changetitle (*url, nurl);
#endif

  /* Initialize logging.  */
  log_init (opt.lfilename, append_to_log);

  DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", version_string,
	   OS_TYPE));
  /* Open the output filename if necessary.  */
  if (opt.output_document)
    {
      if (HYPHENP (opt.output_document))
	opt.dfp = stdout;
      else
	{
	  opt.dfp = fopen (opt.output_document, "wb");
	  if (opt.dfp == NULL)
	    {
	      perror (opt.output_document);
	      exit (1);
	    }
	}
    }

#ifdef WINDOWS
  ws_startup ();
#endif

  /* Setup the signal handler to redirect output when hangup is
     received.  */
#ifdef HAVE_SIGNAL
  if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
    signal(SIGHUP, redirect_output_signal);
  /* ...and do the same for SIGUSR1.  */
  signal (SIGUSR1, redirect_output_signal);
  /* Writing to a closed socket normally signals SIGPIPE, and the
     process exits.  What we want is to ignore SIGPIPE and just check
     for the return value of write().  */
  signal (SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGNAL */

  status = RETROK;		/* initialize it, just-in-case */
  recursive_reset ();
  /* Retrieve the URLs from argument list.  */
  for (t = url; *t; t++)
    {
      char *filename, *new_file;
      int dt;

      status = retrieve_url (*t, &filename, &new_file, NULL, &dt);
      if (opt.recursive && status == RETROK && (dt & TEXTHTML))
	status = recursive_retrieve (filename, new_file ? new_file : *t);
      FREE_MAYBE (new_file);
      FREE_MAYBE (filename);
    }

  /* And then from the input file, if any.  */
  if (opt.input_filename)
    {
      int count;
      status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
      if (!count)
	logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
		   opt.input_filename);
    }
  /* Print the downloaded sum.  */
  if (opt.recursive
      || nurl > 1
      || (opt.input_filename && opt.downloaded != 0))
    {
      logprintf (LOG_NOTQUIET,
		 _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
		 time_str (NULL), legible (opt.downloaded), opt.numurls);
      /* Print quota warning, if exceeded.  */
      if (opt.quota && opt.downloaded > opt.quota)
	logprintf (LOG_NOTQUIET,
		   _("Download quota (%s bytes) EXCEEDED!\n"),
		   legible (opt.quota));
    }
  if (opt.convert_links)
    {
      convert_all_links ();
    }
  log_close ();
  cleanup ();
  if (status == RETROK)
    return 0;
  else
    return 1;
}

/* Hangup signal handler.  When wget receives SIGHUP or SIGUSR1, it
   will proceed operation as usual, trying to write into a log file.
   If that is impossible, the output will be turned off.  */

#ifdef HAVE_SIGNAL
static RETSIGTYPE
redirect_output_signal (int sig)
{
  char tmp[100];
  signal (sig, redirect_output_signal);
  /* Please note that the double `%' in `%%s' is intentional, because
     redirect_output passes tmp through printf.  */
  sprintf (tmp, _("%s received, redirecting output to `%%s'.\n"),
	   (sig == SIGHUP ? "SIGHUP" :
	    (sig == SIGUSR1 ? "SIGUSR1" :
	     "WTF?!")));
  redirect_output (tmp);
}
#endif /* HAVE_SIGNAL */

Um Symbol em português símbolo, são objetos que representam os nomes e algumas Strings dentro do interpretador Ruby. Eles são gerados usando o caractere : (dois pontos). Lembrando que Ruby é uma linguagem puramente orientada a objeto, os símbolos são objetos instanciados da classe Symbol, entretanto o uso mais comum para um símbolo é dentro dos objetos da classe Hash.

Um Hash é uma coleção como dicionário de chaves únicas e seus valores. Também chamados de Arrays associativos, eles são semelhantes aos Arrays comuns, mas onde uma matriz usa inteiros como seu índice, um Hash permite a utilização de qualquer tipo de objeto.

Ruby - Symbol e Hash

Ruby – Symbol e Hash

Exemplo:

Neste exemplo utilizamos símbolos e imprimimos seus IDs de objetos e os utilizamos dentro de tipos hash no qual podemos os referenciar como dicionário contendo chaves e valores.

Ruby

# Desenvolvimento Aberto
# Simbolos-hash.rb

# Lembre-se que Ruby é uma linguagem
# Puramente orientada a objeto
puts "IDs dos objetos Simbolos:"
puts :beatles.object_id 
puts :rollinsStones.object_id

# Para atribuir num valor ao simbolo
# usa-se um hash 
puts "\nConteudo de um hash:"
bandas = {:beatles => "Come together", :rollinsStones => "Satisfaction" }
puts bandas 

# Você pode utilizar um hash referenciando seus sibolos
puts "\nMinhas musicas:"
puts bandas[:beatles]
puts bandas[:rollinsStones]

 

 

A linguagem de programação Ruby possui uma instrução “mágica” que suspende as regras da Orientação a Objeto, ligando blocos de procedimento a um método ou uma função, esta incomum instrução chamada Yield, permite que métodos sejam chamados como um argumento implícito e permitindo que os blocos tenham seus próprios argumentos, ou seja Yield passa para o método o conteúdo de um bloco quando interligados através de suas sintaxes, podendo ainda trocar parâmetros entre si.

Ruby - Yield

Ruby – Yield

Exemplo:

Neste exemplo criamos duas funções e dois blocos no qual interagem entre si através da instrução Yield.

Ruby

# Desenvolvimento Aberto
# Block-yield.rb

# cria uma função padrão
def funcao
  # Esta instrução fornce uma conexão com um bloco
  puts "Yield conecta um bloco a uma function"
  puts "podendo substituir o conteudo do metodo"
  puts "O bloco executa:"
  yield
end

# função com parametros
def parametros
  yield "Desenvolvimento Aberto"
end

# O bloco será executado no lugar do yield
funcao {
  puts "Desenvolvimento"
  puts "Aberto"
}

# passa um parametro
parametros { |x| puts "imprime o valor do campo yield: #{x}"}

HTML5 ou Hypertext Markup Language, versão 5 é uma linguagem para estruturação e apresentação de conteúdo para a World Wide Web e é uma tecnologia chave da Internet, está na quinta versão da linguagem HTML. Esta nova versão traz consigo importantes mudanças quanto ao papel do HTML no mundo da Web, através de novas funcionalidades como semântica e acessibilidade.

Claro, houve mudanças na linguagem HTML em si. Algumas Tags foram adicionadas em comparação ao padrão HTML 4, e um número considerável também foram excluídas. Provavelmente o maior ajuste para aqueles que usaram ​​o HTML4 não é realmente o HTML em si, mas a relação entre a mudança de HTML e CSS. Em HTML5 (como em HTML), a linguagem de marcação descreve o que significam os vários elementos. CSS é usado para descrever como as coisas se parecem.

CSS3 é a mais nova versão das famosas Cascading Style Sheets ou simplesmente CSS, onde se define estilos para páginas web com efeitos de transição, imagem, e outros, que dão um estilo novo às páginas Web 2.0 em todos os aspectos de design do layout. A principal função do CSS3 é abolir as imagens de plano de fundo, bordas arredondadas, apresentar transições e efeitos para criar animações de vários tipos, como um simples relógio de ponteiros.

Google Cloud - HTML5 e CSS3

Google Cloud – HTML5 e CSS3

Computação nas Nuvens

Agora que você já sabe como funciona a tecnologia Cloud do Google App Engine e como o funciona o ambiente de SandBox no qual nossa aplicação Python roda, vamos nos aprofundar um pouco mais nas linguagens de scripts para a Web, pois não há como existir computação nas nuvens sem a boa e velha linguagem de scripts chamada HTML. Em sua versão mais recente o HTML5 possui como uma melhor amiga, a linguagem de scripts que também ganhou uma cara nova e é chamada de CSS3.

Entretanto na arquitetura Cloud as coisas são um pouco diferentes do que são em um servidor web padrão, como por exemplo, os diretórios da web, em um servidor web você possui um diretório pré-estabelecido no qual pode utilizar, criando subdiretórios para scripts, imagens entre outros arquivos e apenas os referenciar utilizando scripts do qual você já esta acostumado.

Na tecnologia Cloud do Google quem comanda toda a aplicação é um arquivo YAML, então os scripts que, por exemplo chamam uma imagem em uma pagina HTML, só podem encontrar a imagem se ela ou o diretório onde a imagem se encontra estiver declarado nos handlers do arquivo que manipula a aplicação, como podemos ver nos códigos abaixo.

Diretórios Google Cloud App

  1. A imagem open-source.jpg que você vê na pagina esta localizada dentro de uma pasta chamada static na raiz da aplicação, você pode perceber que a tag “img src” é utilizada sem o caractere “/” fazendo referencia a um diretório, quem controla onde as imagens serão encontradas é a instrução handlers do arquivo yaml.
  2.  O ícone favicon.ico (16×16) utilizado pelo navegador se encontra na raiz da aplicação junto com o arquivo main.py, mais uma vez quem controla este ícone é a instrução handlers do arquivo yaml.

 

Multi Plataforma

Considerando que nossa aplicação roda em um navegador web, você pode utiliza-la de um sistema operacional de sua preferencia.

Você pode ver esta aplicação direto das nuvens: http://devabertolinux.appspot.com/

Para configurar sua primeira aplicação Google Cloud Linux: Hello World Google Cloud App Engine

Para Windows e Mac utilize o Google Cloud App Engine Launcher: Instalação e Hello World

Exemplo:

Neste exemplo criamos uma aplicação padrão no Google Cloud Engine, e utilizamos para programação a linguagem Python e através delas criamos uma variável no qual atribuímos um script contendo HTML5 e CSS3 para criar nossa pagina.

Yaml

application: devabertolinux
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /(.*\.(gif|png|jpg))$
  static_files: static/\1
  upload: static/.*\.(gif|png|jpg)$

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Python

#!/usr/bin/env python
#
#########################################
# Desevolvimento Aberto
#########################################
# E-mail: desenvolvimento.aberto@live.com
#
# Cloud Computing
# Python - HTML5 - CSS3 - Javascript
# main.py

import webapp2

devhtml = """
<!DOCTYPE HTML>
<html>
  <head>
     <title>Cloud - Desenvolvimento Aberto - Google APP Engine</title>
        <style type = "text/css">
           body { background-color: white; }
           h1   { color: #191970; }
           h3   { color: #53868B; }
           p    { color: #27408B; }
        </style>
  </head>
<body>
 <h1>Desenvolvimento Aberto</h1>
   <h3>Cloud Computing - HTML5 - CSS3 - Javascript</h3>
   <p>
     <img src = "open-source.jpg" alt = "Open Source" />
   </p>
   <h2>C&oacute;digo Aberto de melhor qualidade</h2>
     <p>Desenvolvimento Aberto &eacute; formado para educar sobre e defender</br>
        os benef&iacute;cios do c&oacute;digo aberto e de construir pontes entre os</br>
        diferentes c&iacute;rculos eleitorais na comunidade de c&oacute;digo aberto.</p>
</body>
</html>
"""

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write(devhtml)

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)