terça-feira, 30 de novembro de 2010

SQL, Formatação de Data e o Sistema Operacional

Quero hoje compartilhar uma solução bastante interessante, viabilizada pelo nosso colega Rafael Farias.

Problema:

A executar uma consulta SQL que envolva data, se o sistema operacional estiver em inglês acontece uma mágica e o mês vira dia e o dia vira mês.

Solução:

Como utilizamos os componentes da DevArt (que aliás aproveito para indicar) o Farias teve a feliz idéia de fazer uma classe descendente do TMSConnection sendo que logo após a conexão efetiva com o banco de dados ele definiu o formato da data da sessão no servidor de banco de dados baseado na configuração de data do sistema operacional do cliente.

O "pulo do gato" foi converter a string '03/02/01' para TDateTime e verificar qual número "virou" dia e dai por diante.

Bom, sem mais delongas, mostro abaixo a unit desenvolvida:

unit Unt_G4Connection;

interface

uses
  Classes, Windows, SysUtils, db, MSAccess;

type

  Tg4Connection = class(TMSConnection)
  protected
    procedure SetDateFormat;
    procedure DoConnect; override;
  end;

implementation

{ Tg4Connection }

procedure Tg4Connection.DoConnect;
begin
  inherited;
  Self.SetDateFormat;
end;

procedure Tg4Connection.SetDateFormat;
var
dDecode    : TDateTime;  //Buffer para a data convertida
sFormat    : string;     //Buffer para a instrução SQL SET DATEFORMAT
wDay       : Word;       //Buffer para o DIA
wMonth     : Word;       //Buffer para o MÊS
wYear      : Word;       //Buffer para o ANO
qSetFormat : TMSQuery;   //Executor da instrução SQL
begin
  sFormat := 'SET DATEFORMAT ';
  wDay := 0;
  wMonth := 0;
  wYear := 0;
  qSetFormat := nil;

  try
    qSetFormat := TMSQuery.Create(nil);
    qSetFormat.Connection := Self;

    dDecode := StrToDateTime('03/02/01');
    DecodeDate(dDecode, wYear, wMonth, wDay);

    case wDay of
    3: if wMonth = 2 then
         sFormat := sFormat +'DMY'
       else
         sFormat := sFormat +'DYM';
    2: if wMonth = 3 then
         sFormat := sFormat +'MDY'
       else
         sFormat := sFormat +'YDM';
    1: if wMonth = 3 then
         sFormat := sFormat +'MYD'
       else
         sFormat := sFormat +'YMD'
    end;

    qSetFormat.SQL.Clear;
    qSetFormat.SQL.Add(sFormat);
    qSetFormat.Execute;

  finally
    if Assigned(qSetFormat) then
      qSetFormat.Free;
  end;

end;

end.

Enjoy!

2 comentários:

Gedean Dias disse...

Tenho utilizado este código aqui para resolver o problema:

function SQLDate(const Date: TDateTime): string;
begin
Result := SysUtils.FormatDateTime('yyyy"-"mm"-"dd', Date);
end;

pinçado de http://www.delphidabbler.com/software/codesnip

Erick Sasse disse...

Basta passar sempre no formato yyyymmdd, que você nunca vai precisar se preocupar com formatos do servidor nem do cliente.

Minha lista de blogs