Translate

quinta-feira, 29 de outubro de 2015

Formatar e Comparar arquivo XML no Notepad++

O Notepad++ é um utilitários que aumenta muito a produtividade pois oferece diversos recursos de forma nativa e também através de plugin que são indispensáveis para quem atua no suporte e desenvolvimento quando há manipulação de arquivos: TXT, CSV, XML e outros.

Problema: Como identificar diferença entre dois arquivos XML com muitos elementos?

Solução:
- Notepad++ e dois plugins: XML Tools e Compare

Como?
- Abrir o Notepad++;
- Clicar no menu Plugins, Plugin Manager, Plugin Manager;
- Instalar Compare e XML Tools que estão na aba Avaliable;

Para Formatar:
- Abrir os dois arquivos XML;
- Clicar no menu Plugins, XML Tools, Pretty print (XMl only - with line breaks) ou Ctrl+Alt+Shift+B para formatar o arquivo que estiver em foco;
- Repetir o processo de formatação nos demais arquivos XML;
- Salvar os arquivos;

Para Comparar:
- Clique no menu Compare, Compare ou Alt+D;

Fonte: http://stackoverflow.com/questions/3961217/how-to-format-xml-in-notepad

sábado, 25 de agosto de 2012

Dias da Semana entre SQL Server e Firebird

A função que retorna o dia da semana no SQL Server e Firebird tem resultados diferentes.

Firebird:
SELECT
  EXTRACT(WEEKDAY FROM CAST('19.08.2012' AS DATE)) AS Domingo,
  EXTRACT(WEEKDAY FROM CAST('20.08.2012' AS DATE)) AS Segunda,
  EXTRACT(WEEKDAY FROM CAST('21.08.2012' AS DATE)) AS Terca,
  EXTRACT(WEEKDAY FROM CAST('22.08.2012' AS DATE)) AS Quarta,
  EXTRACT(WEEKDAY FROM CAST('23.08.2012' AS DATE)) AS Quinta,
  EXTRACT(WEEKDAY FROM CAST('24.08.2012' AS DATE)) AS Sexta,
  EXTRACT(WEEKDAY FROM CAST('25.08.2012' AS DATE)) AS Sabado
FROM RDB$DATABASE
O resultado para o Firebird foi:
0 - Domingo; 1 - Segunda; 2 - Terça; 3 - Quarta; 4 - Quinta; 5 - Sexta; 6 - Sábado;

SQL Server: Sem alterar a configuração do DATEFIRST.
USE NOME_BANCO
GO
SELECT
  @@DATEFIRST
SELECT 
  DATEPART(WEEKDAY, '2012-08-19') AS Domingo,
  DATEPART(WEEKDAY, '2012-08-20') AS Segunda,
  DATEPART(WEEKDAY, '2012-08-21') AS Terça,
  DATEPART(WEEKDAY, '2012-08-22') AS Quarta,
  DATEPART(WEEKDAY, '2012-08-23') AS Quinta,
  DATEPART(WEEKDAY, '2012-08-24') AS Sexta,
  DATEPART(WEEKDAY, '2012-08-25') AS Sábado
O resultado para o SQL Server foi:
1 - Domingo; 2 - Segunda; 3 - Terça; 4 - Quarta; 5 - Quinta; 6 - Sexta; 7 - Sábado;

SQL Server: Alterando a configuração do DATEFIRST para 4.
USE NOME_BANCO
GO
SET DATEFIRST = 4
SELECT 
  DATEPART(WEEKDAY, '2012-08-19') AS Domingo,
  DATEPART(WEEKDAY, '2012-08-20') AS Segunda,
  DATEPART(WEEKDAY, '2012-08-21') AS Terça,
  DATEPART(WEEKDAY, '2012-08-22') AS Quarta,
  DATEPART(WEEKDAY, '2012-08-23') AS Quinta,
  DATEPART(WEEKDAY, '2012-08-24') AS Sexta,
  DATEPART(WEEKDAY, '2012-08-25') AS Sábado
O resultado para o SQL Server foi diferente do anterior:
4 - Domingo; 5 - Segunda; 6 - Terça; 7 - Quarta; 1 - Quinta; 2 - Sexta; 3 - Sábado;

SQL Server: Solução ideal quando você não quer que o DATEFIRST influencie nos resultados.
USE NOME_BANCO
GO
SET DATEFIRST = 7 -- Padrão
SELECT 
  (DATEPART(DW, '2012-08-19') + @@DATEFIRST) % 7 as Domingo,
  (DATEPART(DW, '2012-08-20') + @@DATEFIRST) % 7 as Segunda,
  (DATEPART(DW, '2012-08-21') + @@DATEFIRST) % 7 as Terça,
  (DATEPART(DW, '2012-08-22') + @@DATEFIRST) % 7 as Quarta,
  (DATEPART(DW, '2012-08-23') + @@DATEFIRST) % 7 as Quinta,
  (DATEPART(DW, '2012-08-24') + @@DATEFIRST) % 7 as Sexta,
  (DATEPART(DW, '2012-08-25') + @@DATEFIRST) % 7 as Sábado

SET DATEFIRST = 4
SELECT 
  (DATEPART(DW, '2012-08-19') + @@DATEFIRST) % 7 as Domingo,
  (DATEPART(DW, '2012-08-20') + @@DATEFIRST) % 7 as Segunda,
  (DATEPART(DW, '2012-08-21') + @@DATEFIRST) % 7 as Terça,
  (DATEPART(DW, '2012-08-22') + @@DATEFIRST) % 7 as Quarta,
  (DATEPART(DW, '2012-08-23') + @@DATEFIRST) % 7 as Quinta,
  (DATEPART(DW, '2012-08-24') + @@DATEFIRST) % 7 as Sexta,
  (DATEPART(DW, '2012-08-25') + @@DATEFIRST) % 7 as Sábado
O resultado para o SQL Server foi:
1 - Domingo; 2 - Segunda; 3 - Terça; 4 - Quarta; 5 - Quinta; 6 - Sexta; 0 - Sábado;
1 - Domingo; 2 - Segunda; 3 - Terça; 4 - Quarta; 5 - Quinta; 6 - Sexta; 0 - Sábado;

SQL Server: Para ter o mesmo resultado do Firebird.
USE NOME_BANCO
GO
SELECT 
  (DATEPART(DW, '2012-08-19') + @@DATEFIRST - 1) % 7 as Domingo,
  (DATEPART(DW, '2012-08-20') + @@DATEFIRST - 1) % 7 as Segunda,
  (DATEPART(DW, '2012-08-21') + @@DATEFIRST - 1) % 7 as Terça,
  (DATEPART(DW, '2012-08-22') + @@DATEFIRST - 1) % 7 as Quarta,
  (DATEPART(DW, '2012-08-23') + @@DATEFIRST - 1) % 7 as Quinta,
  (DATEPART(DW, '2012-08-24') + @@DATEFIRST - 1) % 7 as Sexta,
  (DATEPART(DW, '2012-08-25') + @@DATEFIRST - 1) % 7 as Sábado
O resultado para o SQL Server foi:
0 - Domingo; 1 - Segunda; 2 - Terça; 3 - Quarta; 4 - Quinta; 5 - Sexta; 6 - Sábado;
O resultado para o Firebird foi:
0 - Domingo; 1 - Segunda; 2 - Terça; 3 - Quarta; 4 - Quinta; 5 - Sexta; 6 - Sábado;

Muito cuidado para quem está migrando de banco, espero que você tenha testes para isso :)

Fonte:
- http://blog.sqlauthority.com/2007/04/22/sql-server-datefirst-and-set-datefirst-relations-and-usage
- www.kodyaz.com/articles/get-week-day-name-of-date-using-t-sql.aspx

quarta-feira, 22 de agosto de 2012

Desabilitar e Habilitar Trigger no SQL Server

Essa semana eu precisei fazer uma manutenção no banco de dados de um cliente novo, que por engano, acabou cadastrando dados da empresa "A" na empresa "B", até então uma tarefa simples se não tivesse uma Trigger no meio da história que mantém uma determinada data atualizada conforme a regra de negócio do sistema.

Após executar o script abaixo no ambiente de testes, ocorreu um alerta no SSMS: Warning: Null value is eliminated by an aggregate or other SET operation e o campos em questão havia ficado zerado, ou seja, bug!

Entendendo melhor o comportamento da Trigger, a solução foi desabilitar e habilitar a trigger durante a execução do script, fiocu assim:
USE NOME_BANCO
GO

DECLARE @EMPRESA_ORIGEM UNIQUEIDENTIFIER ='{E79572FB-80EF-44E7-ACD5-F8771AFCBA8D}';
DECLARE @EMPRESA_DESTINO UNIQUEIDENTIFIER ='{E03E1A64-AC16-4CD3-AB87-CF2A62264D22}';

-- Desabilita a Trigger 
ALTER TABLE TABELA DISABLE TRIGGER TABELA_AIUD0;

-- Move os dados para outra empresa
UPDATE TABELA SET EMPRESA_ID = @EMPRESA_DESTINO WHERE EMPRESA_ID = EMPRESA_ORIGEM;

-- Habilita a Trigger
ALTER TABLE TABELA ENABLE TRIGGER TABELA_AIUD0;

terça-feira, 17 de abril de 2012

SQL Prompt 5 para SQL Server Management Studio

O SQL Prompt da Red-Gate é uma ferramenta que se integra com o SQL Server Managemente Studio com objetivo de aumentar a produtividade através do seu poderoso code-complete, code-snippets e formatação de código (útil para padronizar o código facilitando diff no controle de versão e reviews).

O inteligente (intelisense) consegue carregar os campos que você precisa, segue um exemplo do relacionamento entre as tabelas Pedidos e Itens de Pedidos, após digitar inner join on é listado a opção de relacionamento:

Aproveite para testar a versão trial por 14 dias e boa sorte.

segunda-feira, 5 de setembro de 2011

Exemplo de Padrão de Projeto Factory em Delphi

O exemplo será apresentado através de uma necessidade, retornar o nome de uma pessoa que pode ser (Cliente, Agência ou Vendedor).

Minha definição de Factory nesse exemplo seria passar a responsabilidade da criação do objeto TPessoa para outro objeto.

Essa unit é responsável pela classe base TPessoa na qual possui um método Nome no qual será implementado em outro momento.
unit Pessoa;

interface

type
  TPessoa = class
    function Nome: string; virtual; abstract;
  end;

implementation

end.

Essa unit PessoaCliente é responsável pela classe TPessoaCliente que herda da classe base TPessoa na qual implementará o método Nome, observe que ele irá mostrar o nome da classe e o nome da pessoa para facilitar o desenvolvimento.
unit PessoaCliente;

interface

uses
  Pessoa;

type
  TPessoaCliente = class(TPessoa)
    function Nome: string; override;
  end;

implementation

function TPessoaCliente.Nome: string;
begin
  Result := ClassName + ': Microsoft';
end;

end.

Essa unit PessoaVendedor é semelhante a da classe TPessoaCliente
unit PessoaVendedor;

interface

uses
  Pessoa;

type
  TPessoaVendedor = class(TPessoa)
  public
    function Nome: string; override;
  end;

implementation

function TPessoaVendedor.Nome: string;
begin
  Result := ClassName + ': Bruno';
end;

end.

Essa unit PessoaFactory é responsável por criar e devolver a instanciar do objeto de acordo com o parâmetro informado TTipoPessoa.
Observe que o retorno é do tipo base TPessoa, facilitando a ampliação para outras classes como, por exemplo, TUsuario.
unit PessoaFactory;

interface

uses
  Classes,
  Pessoa;

type
  TTipoPessoa = (tpCliente, tpAgencia, tpVendedor);

  // Simple Factory: Retorna apenas a instancia, diferente do Abstract que pode retornar vários métodos
  TPessoaFactory = class
  public
    function CriarPessoa(const ATipoPessoa: TTipoPessoa): TPessoa;
  end;

implementation

uses
  PessoaCliente,
  PessoaAgencia,
  PessoaVendedor;

function TPessoaFactory.CriarPessoa(const ATipoPessoa: TTipoPessoa): TPessoa;
begin
  Result := nil;
  case ATipoPessoa of
    tpCliente:
      Result := TPessoaCliente.Create;
    tpAgencia:
      Result := TPessoaAgencia.Create;
    tpVendedor:
      Result := TPessoaVendedor.Create;
  end;
end;

end.

A unit Principal só tem conhecimento da unit PessoaFactory, que cria e chama o método nome de acordo com o parâmetro informado.
procedure TFormPrincipal.ButtonListarPessoasClick(Sender: TObject);
var
  Pessoa: TPessoaFactory;
begin
  Pessoa := TPessoaFactory.Create;
  try
    Memo.Lines.Add(Pessoa.CriarPessoa(tpCliente).Nome);
    Memo.Lines.Add(Pessoa.CriarPessoa(tpAgencia).Nome);
    Memo.Lines.Add(Pessoa.CriarPessoa(tpVendedor).Nome);
  finally
    Pessoa.Free;
  end;
end;


Mais detalhes no repositório https://bitbucket.org/brunosanson/design-patterns-em-delphi/