jueves, 18 de diciembre de 2008

Guardar archivos en SQL desde Delphi ??

Pues al principio me parecía imposible o tedioso, hasta que platicando con un amigo me ha dado una opción bastante eficiente; decido compartirla para que también les saque de apuros !!! TOMA NOTA :

PASO 1: Puedes tomar como ejemplo la siguiente tabla creada en SQL 2005 pero que para las versiones anteriores de SQL es lo mismo :

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Archivos_Adjuntos](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Nombre] [nchar](100) NOT NULL,
[Tipo_MIME] [nchar](50) NOT NULL,
[datos] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

PASO 2:  Una vez halla llamado la tabla desde Delphi y tengas lista tu forma utiliza el siguiente codigo para guardar un archivo en la tabla:

procedure TForm2.CargarArchivo;
var FStr: TFileStream; 
BlobStr: TStream; 

begin 
if OpenDialog1.Execute then 
begin 
FStr := 
TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone); 
try 
tAdjuntos.Append; 
tAdjuntosNombre.AsString := ExtractFileName(OpenDialog1.FileName); tAdjuntosTipo_MIME.AsString := 
'application/octect-stream'; 
BlobStr := 
tAdjuntos.CreateBlobStream(tAdjuntosdatos, bmWrite); 
try 
BlobStr.CopyFrom(FStr, FStr.Size); 
finally 
BlobStr.Free; 
end; 
tAdjuntos.Post; 
finally 
FStr.Free; 
end; 
end; 
end;

PASO 3: Una vez guardado el archivo en la base de datos, usa el siguiente procedimiento desde delphi para descargarlo:

procedure DescargarArchivo;
var
  BlobStr: TStream;
  FStr: TFileStream;
begin
  if tAdjuntos.IsEmpty then
    Exit;
  if SaveDialog1.FileName <> '' then
    SaveDialog1.FileName := TrailingPathDelimiter(ExtractFilePath(SaveDialog1.FileName)) + Trim(tAdjuntosNombre.AsString)
  else
    SaveDialog1.FileName := Trim(tAdjuntosNombre.AsString);
  if SaveDialog1.Execute then
  begin
    BlobStr := tAdjuntos.CreateBlobStream(tAdjuntosdatos, bmRead);
    try
      FStr := 
TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareExclusive);
      try
        FStr.CopyFrom(BlobStr, BlobStr.Size);
      finally
        FStr.Free;
      end;
    finally
      BlobStr.Free;
    end;
  end;
end;




jueves, 13 de noviembre de 2008

Búsqueda personalizada




sábado, 11 de octubre de 2008

Collation de SQL

Siempre que he trabajado con bases de datos de SQL, llega el momento en que he tenido problemas con el collation... y se me dificulta siempre encontrar una respuesta al porque de este problema, pero bueno siempre digo que no hay problema que no tenga solucion.

Aca les adjunto un codigo que les puede ser de utilidad siempre y cuando acostumbren a identificar de una forma estandar las trablas que van creando (yo acostumbro nombrarlas asi 'tbl_') y siempre y cuando la base de datos no este en uso al momento de ejecutar este procedimiento, no te digo que la tarea esta resuelta porque habran tablas que no se modificaran asi de facil por lo que tamben te tocara un poco de trabajo manual, pero igual puede que sea menor a realizarlo todo manual; el procedimiento de select podras utilizarlo para ubicar las tablas que no se han podido modificar con este procedimiento.

Suerte, aca va el codigo.

declare @tabla varchar(100),
@campo varchar(100),
@tamanio int,
@query varchar(300)

declare base cursor for
select distinct a.name, --> nombre de la tabla
b.name, --> nombre del campo
b.prec --> tamaño del campo tipo varchar
from sysobjects a, syscolumns b
where a.id = b.id
and a.type = 'U'
and a.name <> 'dtproperties'
and b.collation is not null
and b.collationid <> 53288 --> Callationid de
Modern_Spanish_CI_AS
and substring(a.name,1,4) = 'tbl_'
and b.isnullable = 1 --> selecciono solo los campos que permiten null
and b.prec is not null --> selecciono los campos que no son tipo text
and b.collation <> 'Modern_Spanish_CI_AS'

/* and b.name = ''

ESTA ULTIMA LINEA USALA PARA EJECUTAR LA CONSULTA Y VER QUE TABLA TENDRAS QUE MODIFICAR MANUALMENTE*/

open base
fetch base into
@tabla,
@campo,
@tamanio

while @@fetch_status = 0
begin
set @query = ' ALTER TABLE [' +
ltrim(rtrim(@tabla)) + --> nombre de la tabla
'] ALTER COLUMN [' +
ltrim(rtrim(@campo)) + --> nombre del campo
'] [varchar] (' + --> cuando son tipo text esto cambia
ltrim(rtrim(cast(@tamanio as varchar(5)))) + --> tamaño
--del campo, esto no se pone cuando son tipo text

') COLLATE Modern_Spanish_CI_AS ' + --> nuevo collation
'NULL' + --> cuando el campo no permite que sea null esta
--linea se quita

exec (@query)

fetch base into
@tabla,
@campo,
@tamanio
end

close base
deallocate base


Este codgio deveras ejecutarlo un minimo de cuatro veces realizandole las modificaciones necesarias:
  • para campos varchar que permiten null deja el codigo tal y como esta
  • para campos varchar que no permiten null cambia en linea b.isnullable = 1 el 1 por el 0
  • para campos text que permiten null cambia la linea b.prec is not null por b.prec is null
  • para campos text que no permiten null has los dos cambios anteriores.