domingo, 27 de mayo de 2018

PostgreSQL – Alternatvas de Programación


PostgreSQL – Alternatvas de Programación

Comandos de avanzada

Veamos algunos comandos que nos hacen la vida más facil.

Truncate.

El comando TRUNCATE TABLE se utiliza para eliminar todos los datos de una o más tablas existentes. También puede utilizar el comando DROP TABLE pero este no solo elimina los datos sino la estructura de la tabla.
Tiene el mismo efecto del comando DELETE, pero es más rápido y recupera espacio en disco de inmediato. Es muy útil para el borrado de datos en tablas grandes.

TRUNCATE [ TABLE ] [ ONLY ] NAME [ * ] [, ... ]
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

NAME:   El nombre (opcionalmente esquema cualificado) de una tabla para truncar. Si sólo se especifica antes del nombre de tabla, sólo esa tabla se trunca. Si no se especifica ONLY, los datos de TABLA y todas los datos de sus tablas descendientes (si los hay) se truncan. Opcionalmente, * se puede especificar después de que el nombre de la tabla para indicar explícitamente que las tablas descendientes están incluidos.
RESTART IDENTITY: Reiniciar automáticamente secuencias de propiedad de columnas de la tabla truncada (s).
CONTINUE IDENTITY:  No cambie los valores de las secuencias. Este es el valor predeterminado.
CASCADE: Truncar automáticamente todas las tablas que tienen referencias de clave externa a cualquiera de las tablas con nombre, o para cualquier tabla agregan al grupo debido a CASCADE.
RESTRICT: Negarse a truncar si alguna de las mesas tienen referencias de clave externa de las tablas que no figuran en el comando. Este es el valor predeterminado.

Extract: muy facil de usar y nos permite comparar dos tablas de forma rápida y eficiente.
Copy: Copia desde y hacia el servidor de datos. Este comando permite cargar y exportr datos en intervalos de tiempos bastante generosos.
En este ejemplo vamos a utilizar winscp (comandos) para conectar al Servidor Linux desde un cliente windows, copiar un archivo a la carpeta /data del mismo y luego cargarla directamente a una tabla de una base de datos postgres.
Usar, entre otros:
  uses Shellapi, Windows, SysUtils, etc.
Componenetes:   
  exeScript: TZSQLProcessor; //Compnenete ZEOS Para ejecutar el comando copy

copy
Tabla(campo1, campo2... campo_n)
from '/xxxx/filename.txt' WITH CSV HEADER DELIMITER '|';

  Memo1 : TMemo; //Para lanzar un .bat dinámico
  Label4 : TLabel; //Mostrar el tiempo gastado.
  OpenTextFileDialog1: TOpenTextFileDialog;
  Button1: TButton;

Definir:
const
  unMillon = 1000000;
var
  Frecuencia, X, Y: Int64; //Para determinar el intervalo de tiempo gastado

Function GetShortFileName(Const FileName : String) : String;
var
 aTmp: array[0..255] of char;
begin
 if GetShortPathName(PChar(FileName), aTmp, Sizeof(aTmp)-1)=0 then
 Result := FileName
 else
 Result := StrPas(aTmp);
end;

function WinExecAndWait32(FileName:String; Visibility:integer):integer;
var
  zAppName:array[0..512] of char;
  zCurDir:array[0..255] of char;
  WorkDir:String;
  StartupInfo:TStartupInfo;
  ProcessInfo:TProcessInformation;
  Resultado,exitCode: DWord;
begin
  StrPCopy(zAppName,FileName);
  GetDir(0,WorkDir);
  StrPCopy(zCurDir,WorkDir);
  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.cb := Sizeof(StartupInfo);

  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  CreateProcess(nil,
    zAppName,            { pointer to command line string }
    nil,                           { pointer to process security attributes}
    nil,                           { pointer to thread security attributes}
    false,                         { handle inheritance flag }
    CREATE_NEW_CONSOLE or          { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil,                           { pointer to new environment block }
    nil,                           { pointer to current directory name }
    StartupInfo,                   { pointer to STARTUPINFO }
    ProcessInfo);

  {Espera a que termine la ejecucion}
  {Wait until execution finish}
  repeat
    exitCode := WaitForSingleObject( ProcessInfo.hProcess,1000);
    Application.ProcessMessages;
  until (exitCode <> WAIT_TIMEOUT);
  GetExitCodeProcess(ProcessInfo.hProcess,Resultado);
  MessageBeep(0);
  CloseHandle(ProcessInfo.hProcess );
  Result:=Resultado;
end;

procedure TfImportarDlg.Button1Click(Sender: TObject);
var
 valor : integer;
 ruta, path, fileStr, host_db  : string;
 Start : longint;
begin
//Inciar el contador
Windows.QueryPerformanceFrequency(Frecuencia);
  Windows.QueryPerformanceCounter(X);
 
  if OpenTextFileDialog1.Execute then
  begin
     if OpenTextFileDialog1.FileName<>'' then
        ruta := OpenTextFileDialog1.FileName
     else
        exit;
  end
  else
    exit;
 
 host_db := ‘192.168.x.x’; //Ruta del Servidor
  ruta := GetShortFileName(ruta); 
  fileStr := '" /data/archivo_'
           + FormatDateTime('yyyymmdd_hhnn', dmAdm.VerFechaHora)+'.txt"';
  Path :='"'+ ExtractFileDir(Application.ExeName)
  +'\winscp.exe'+'"'+' /ini="'+ ExtractFileDir(Application.ExeName)
  +'\winscp.ini" sftp://root:clave@'+host_db+' /console'
  +' /command "cd /data" "put "'+ pchar(ruta)+ fileStr
  +' chmod 777 '+ fileStr +' exit';

  //Creación del .bat
   memo2.Clear;
   Memo2.Lines.Add('Copiando archivo al Servidor');
   memo2.Text := path;
   memo2.Lines.Add('Exit');

   memo2.Lines.SaveToFile( ExtractFilePath(ParamStr(0)) + 'wintolinux.bat');
   Path :=  ExtractFilePath(ParamStr(0))+ 'wintolinux.bat';
   WinExecAndWait32(path, SW_SHOW);

//  ShellExecute(0, nil,'C:\ftp\wintolinux.bat', nil, nil, SW_SHOWNORMAL);

  exeScript.Script.Text := '';
  cadena := Memo3.Text;
  cadena := StringReplace(cadena,':ruta',QuotedStr(ruta),[]);
  exeScript.Script.Text := cadena;

  memo2.Text := exeScript.Script.Text;
  try
    exeScript.Execute;
    QueryPerformanceCounter(Y);
    Label4.Caption := (FormatFloat('0,', (Y - X) * UnMillon div Frecuencia));
    ShowMessage('Proceso existoso...');
  except
    on e : exception do
     ShowMessage(e.Message);
  end;
end;

DBLink: Conexión entre distinas base de datos en en el mismo servidor o entre servidores diferentes.

Función IF al gusto:

CREATE OR REPLACE FUNCTION public.iifs ( boolean, text, text)
RETURNS text AS
$body$
DECLARE
                rtVal text;
BEGIN
                rtVal := (SELECT case $1 when true then $2 else $3 end);
                RETURN rtVal;
END;
$body$
LANGUAGE 'plpgsql'
IMMUTABLE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

No hay comentarios:

Publicar un comentario