Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   Pasar un .dbf en un directorio a un db sql (https://www.clubdelphi.com/foros/showthread.php?t=89172)

aromigaret 09-10-2015 01:17:02

Pasar un .dbf en un directorio a un db sql
 
Hola, mi problema es el siguiente: Se descargan en un directorio via FTP, varias tablas con formato .dbf. Los nombres de dichas tablas son distintos en cada descarga. Necesito pasar el contenido de las tablas descargadas, a un sql server 2008 conservando el nombre de cada tabla. Todas tienen los mismos campos.

Primero genero la tabla en la db, usando una auxiliar que se encuentra en la db del sql server que tiene el mismo formato que las tablas a pasar:

Código Delphi [-]
 PASAJE.SQL.Text:='SELECT TOP 0 * INTO ' + ARCHIVO + ' FROM AUXILIAR';  
 PASAJE.ExecSQL;


y luego no se como copiar el contenido en esta nueva base creada.

Probe creando un procedimiento almacenado y no funciona:

Código Delphi [-]
        PROCEDIMIENTO.ProcedureName:='VOLCAR';
        PROCEDIMIENTO.Parameters.Refresh;
        PROCEDIMIENTO.Parameters.ParamByName('@ARCHIVO').Value:= QUOTEDSTR('C:\Pedidos\' + ARCHIVO);
        PROCEDIMIENTO.Parameters.ParamByName('@PEDIDO').Value:= COPY(ARCHIVO,1,20) ;
        PROCEDIMIENTO.ExecProc;


y el procedimiento en el server sql es :
Código SQL [-]
ALTER PROCEDURE VOLCAR
  -- Add the parameters for the stored procedure here
  @ARCHIVO NVARCHAR(200),
  @PEDIDO NVARCHAR(20)
AS
BEGIN
   DECLARE @comando NVARCHAR(400)   
   
   SET @comando = 'BULK INSERT DBO.' + @PEDIDO + ' FROM ' + @ARCHIVO + 
     ' WITH (FIELDTERMINATOR = ''|'',ROWTERMINATOR = ''|\n'')'
         
EXEC SP_EXECUTESQL @COMANDO

Si alguien sabe como resolverlo se los agradeceria.

Neftali [Germán.Estévez] 09-10-2015 11:04:33

¿Lo que no funciona es el procedimiento en si, o la llamada?
¿Si ejecutas el procedimiento manualmente funciona?

aromigaret 09-10-2015 18:16:10

Neftalí, gracias por responder. El error lo devuelve el SP, ya que la creación de la tabla y el llamado al SP junto con los parámetros funciona. Estuve investigando mas sobre el tema y vi que existe la función openrowset(), pero no se si es el camino, ya que las pruebas que hice en forma manual es:

Código SQL [-]
DECLARE @sql char(150) 
DECLARE @Driver sysname 
DECLARE @Cadena sysname 
DECLARE @Sentencia sysname 

SET @Driver= '''' + 'Microsoft.Jet.OLEDB.4.0' + '''' 
SET @Cadena= '''' + 'Dbase IV; c:\pedidos\PE069100000810182341.dbf' + '''' 
SET @Sentencia= '''' + 'SELECT * FROM PE069100000810182341' + '''' 

SET @sql='select * FROM OPENROWSET(' + @Driver + ', ' + @Cadena + ', ' + @Sentencia + ')' 

execute (@sql)

y me tira el siguiente error:

El proveedor OLE DB "Microsoft.Jet.OLEDB.4.0" del servidor vinculado "(null)" devolvió el mensaje "Argumento no válido.".
Mens. 7303, Nivel 16, Estado 1, Línea 1
No se puede inicializar el objeto de origen de datos del proveedor OLE DB "Microsoft.Jet.OLEDB.4.0" para el servidor vinculado "(null)".


Hasta ahora lo único que se me ocurre es usar dos adoconnection una que apunte al sql server y otra a una query que cargue una por una las bases que se descarguen y luego ver como pasar los datos de esa query al sql server, pero me parece un cuento chino. Por eso busco algo mas rápido y directo.

aromigaret 10-10-2015 18:15:43

Despues de mucho investigar encontre la solucion. La dejo por si alguien lo necesita. Es para Sql server 2008 en adelante

Primero hay que ejecutar en sql

sp_configure 'show advanced options', 1
reconfigure
go
exec sp_configure 'Ad Hoc Distributed Queries',1
go
reconfigure
go

Esto es para habilitar la opcion Ad Hoc la cual permite la comunicacion con entornos externos de sql

Luego escribir para crear el procedimiento almacenado

Código SQL [-]
CREATE PROCEDURE [dbo].[VOLCAR]
  @ARCHIVO NCHAR(30),          -- NOMBRE DEL .DBF A ACCEDER
  @PATH NCHAR(20),               -- DIRECTORIO DONDE SE ENCUENTRA  POR EJEMPLO 'C:\PEDIDOS\'
  @PEDIDO NCHAR(50)             -- TABLA DONDE DESCARGAR EL CONTENIDO DE  @ARCHIVO
    
AS
BEGIN 
  DECLARE @sql char(400) 
  DECLARE @Driver sysname 
  DECLARE @Cadena sysname 
  DECLARE @Sentencia CHAR(100)
  
  SET NOCOUNT ON;  
  
  EXECUTE ('CREATE TABLE '+ @PEDIDO + '(CANTIDAD NUMERIC(8,2),ARTICULO NCHAR(60), MARCA NCHAR(15), CODIGONUM NCHAR(5))')  
  
  SET @Driver= '''' + 'Microsoft.Jet.OLEDB.4.0' + '''' 
  SET @Cadena= '''' + 'dBase IV; HDR=NO;IMEX=2; DATABASE=' + @PATH + ''''   
  SET @Sentencia= '''' + 'SELECT CANTIDAD,ARTICULO,MARCA,CODIGONUM FROM ' + @ARCHIVO + ''''    
  SET @sql='INSERT INTO ' + @PEDIDO + ' select * FROM OPENROWSET(' + @Driver + ', ' + @Cadena + ', ' + @Sentencia + ')' 
  
  execute (@sql)

y el llamado del procedimeinto desde Delphi es :

Código Delphi [-]
        PROCEDIMIENTO.ProcedureName:='VOLCAR';
        PROCEDIMIENTO.Parameters.Refresh;
        PROCEDIMIENTO.Parameters.ParamByName('@PATH').Value:= 'c:\pedidos\';          // DIRECTORIO DONDE SE ENCUENTRA LA TABLA .DBF
        PROCEDIMIENTO.Parameters.ParamByName('@ARCHIVO').Value:= ARCHIVO_DBF;   // CON LA EXTENSION .DBF INCLUIDA EN EL NOMBRE EJEMPLO 'BASE.DBF'
        PROCEDIMIENTO.Parameters.ParamByName('@PEDIDO').Value:= MIBASENUEVA ;   // LA TABLA DONDE SE GUARDARA LOS DATOS DE LA 'BASE.DBF'
        PROCEDIMIENTO.ExecProc;

Espero que le sea util a alguien.
Saludos


La franja horaria es GMT +2. Ahora son las 23:24:44.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi