Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Actualizar estructura de la Base de Datos (https://www.clubdelphi.com/foros/showthread.php?t=25383)

Durbed 21-09-2005 11:16:14

Actualizar estructura de la Base de Datos
 
Me ha surgido un problema, y es que segun mi aplicacion va creciendo, a la vez crecen las bases de datos. La idea es hacer una pequeña aplicacion, donde se escoja la base de datos sobre la que realizar la actualizacion y el fichero sql que contiene dicha actualizacion.

Lo he intentado hacer mediante este codigo:

Código PHP:

 With IBSQL1 do
        
Begin
          SQL
.Clear;
          
SQL.LoadFromFile(EdSQL.Text);
          
Prepare;
          
ExecQuery;
        
End

y otros similares, con componentes TIBQuery y TIBSQL, pero me da un error en el SQL, el caso es que dicho codigo en SQL funciona si lo ejecuto desde el "EMS Interbase & Firebird Manager", el codigo SQl es el siguiente:

Código PHP:

ALTER PROCEDURE CONTACTO_DIRECCION 
RETURNS 
(
   ...
AS
   ...
BEGIN
   
...
 For 
select cod_contactonom_contactoCOD_DIRECCIONnombre_dirfiscalcalle,   numeromunicipioprovincia from contactos left join direcciones
        on cod_contacto
=c_cont
        order by nom_contacto
cod_contactonombre_dir
        into 
:NUEVO_COD_CONTACTO, :NUEVO_NOM_CONTACTO, :NUEVO_COD_DIRECCION,   :NUEVO_NOMBRE_DIR, :NUEVO_FISCAL, :NUEVO_CALLE, :NUEVO_NUMERO,   :NUEVO_MUNICIPIO, :NUEVO_PROVINCIA
   
... 

El error salta en esa expresion y es el siguiente: "Dynamic SQL error, SQL error code = -104, Token unknown - line 30 char 13 ?." El error se corresponde con: "into :NUEVO_COD_CONTACTO, ..." mas concretamente sobre los dos puntos.

A ver si me pueden ayudar con este error que me trae de cabeza, y como les digo, funciona perfectamente si lo ejecuto desde el EMS.

Un saludo y gracias por aguantar el toston ;) .

teracat 25-08-2006 18:02:55

Actualizar estructura de la Base de Datos
 
Hola:

Quiero hacer lo mismo en mi aplicación, es decir, actualizar la base de datos que utiliza el programa a partir de un fichero que contenga los cambios.

Lo he probado de forma similar a como tu lo haces y me da el mismo error.

¿Conseguiste solucionar el problema? ¿Sabe alguien como realizar esta tarea sin problemas?

Utilizo Delphi 7, Firebird 1.5 y los componentes InterBase Express (los que vienen con Delphi).

He creado un archivo SQL de prueba que contiene:

DROP VIEW VISTA;

CREATE VIEW VISTA (...


Y el error que devuelve es el siguiente:

Dynamic SQL Error
SQL error code = -104
Token unknown - line 3, char 1
CREATE



Muchas gracias por cualquier tipo de ayuda.:D

marceloalegre 25-08-2006 18:19:12

Estimado Durbed, considero que no es muy clara la pregunta, porque por un lado muestras un execquery, y por otro lado muestras un alter procedure de un stored...

No se como trabajas, pero la idea para ejecutar ese stored deberia ser
Código Delphi [-]
with ComponenteIbStoredPredure do
begin
  ParamByName('Parametro1').Value := Loquequieras;
  ParamByName('Parametro2').Value := Loquequieras2;
  ExecProc; //para ejecutar el Stored...
end;

Espero que te sirva, sino aclara un poco mas la situación de como ejecutas el stored que muestras. Saludos

Lepe 25-08-2006 18:44:28

La idea parécese no es ejecutar, sino modificar el código del store procedure.

Existir.. existe el Ib Expert que lo hace muy bien con sus sqlScripts y además es gratis. Si por la causa que sea se quiere hacer dentro del programa, habrá que tener en cuenta algunos detalles:

- El modo de hacerlo es el correcot, un sqlquery y ExecQuery o ExecSql
- Tendrás que cambiar el caracter terminador (mira la ayuda de SET TERM)
Cita:

Empezado por Language reference de interbase 6
SET TERM !!;
CREATE PROCEDURE NUMBERPROC (A INTEGER) RETURNS (B INTEGER) AS
BEGIN
B = 0;
BEGIN
UPDATE R SET F1 = F1 + :A;
UPDATE R SET F2 = F2 * F2;
UPDATE R SET F1 = F1 + :A;
WHEN SQLCODE -803 DO
B = 1;
END
EXIT;
END!!

SET TERM; !!

- Supongo, y solo supongo, que solamente podrás ejecutar una sola instrucción en el sql, es decir, primero haces el "drop view" le das al boton "ejecutar script" (o como le hayas llamado) y despues, haces el "create view" y vuelta a ejecutar.

Saludos

teracat 29-08-2006 10:22:00

Actualizar estructura de la Base de Datos
 
Gracias por vuestras respuestas.

Había pensado en ejecutar instrucción por instrucción, aunque preferiría poder ejectuar todo un fichero de golpe (si es posible, claro :p). Si por lo que sea se ha detectado un error al intentar procesar dicho fichero, nada de lo que se ha ejecutado debería ser validado, de manera que podamos intentar pasar el fichero entero de nuevo. Tengo esta idea porqué no hace mucho hice este mismo procedimiento en otro proyecto con PostgreSQL sin problema, mi duda es si lo podré hacer con Firebird.

Quizá lo que necesite es cambiar de componentes, si es así estaría dispuesto a hacer el cambio.

Cualquier ayuda será bienvenida. Gracias.

teracat 08-09-2006 19:36:59

Posible solución
 
Hola, ya he encontrado una solución al problema que parece que funciona.

Os pongo aquí el código por si a alguien le puede ser útil. Si encontrais algún error, por favor, comentadlo en este foro para que nos entermos. Por supuesto, también se aceptan comentarios, críticas, mejoras, etc. ;)

Ahí va el código:

(Tened en cuenta que se utiliza un FSQL que es del tipo TIBSQL y que la constante cFileExecutorSeparator debe estar definida y usada en el archivo para separar las sentencias [ver ejemplo al final]).

FSQL: TIBSQL; //Faltará inicializarla como es debido :p

const
cFileExecutorSeparator = '--##@##';

function ExecuteFromFile(const AFilename: string): boolean;
var
FileContents: TStrings;
fContentsLeft, fContentsToExe: string;
iPos: integer;
begin
{ Si el fichero no existe no continuamos }
if not FileExists(AFilename) then
begin
Result := False;
exit;
end;
{ Cargar el contenido del fichero }
FileContents := TStringList.Create;
try
FileContents.LoadFromFile(AFilename);
fContentsLeft := FileContents.Text;
finally
FileContents.Free;
end;
if fContentsLeft='' then
Result := True
else
begin
try
if not FSQL.Transaction.Active then FSQL.Transaction.StartTransaction;
Close;
{ Vamos ejecutando hasta que no quede nada }
while fContentsLeft<>'' do
begin
iPos := Pos(cFileExecutorSeparator,fContentsLeft);
if iPos>0 then
begin
fContentsToExe := Copy(fContentsLeft,1,iPos-1);
fContentsLeft := Copy(fContentsLeft,iPos+Length(cFileExecutorSeparator),Length(fContentsLeft));
end
else
begin
fContentsToExe := fContentsLeft;
fContentsLeft := '';
end;
fContentsToExe := Trim(fContentsToExe);
if fContentsToExe<>'' then
begin
{ Aquí está la ejecución la sentencia }
FSQL.SQL.Text := fContentsToExe;
FSQL.Prepare;
FSQL.ExecQuery;
end;
end;
Result := True;
except
on E: Exception do
begin
Result := False;
{ Tratar la excepción como guste }
end;
end;
end;
end;


Ejemplo de script:

--Creamos una vista
DROP VIEW nombre_vista;

--##@##

--Insertamos alguna fila
INSERT INTO tabla(campos) VALUES(valores);

--##@##

--Si queremos hacer más de un insert, deben ir separados
INSERT INTO tabla(campos) VALUES(valores);

--##@##

--Creamos un dominio
CREATE DOMAIN dominio AS tipo;

--##@##

ALTER PROCEDURE "nombre_procedimiento"
(
parámetros
)
RETURNS
(
retorno
)
AS
BEGIN
--Contenido del procedimiento
END

--##@##


Este script os debería funcionar (poniendo nombres reales, claro). :eek:
También comentar que al hacerse todo en la misma transacción, si la función devuelve false deberíamos hacer un Rollback para no validar los cambios.

Espero que sea de ayuda a alguien.

Hasta pronto! :D

maeyanes 08-09-2006 20:51:40

Existe entre los componentes IBX uno llamado TIBScript, cuya función es la que buscan, ejecutar un script para crear o modificar una base de datos.


Saludos...

teracat 12-09-2006 16:27:56

TIBScript
 
He revisado mi paleta y no existe tal componente. Utilizo Delphi 7. He mirado el código y en el archivo IBXConst.pas indica que la versión de las IBX es la 6.0. ¿Podrías decirme qué versiones utilizas tu? ¿Sabes si existe alguna actualización?

Gracias por tu ayuda.:)

teracat 12-09-2006 16:36:20

Ibx 6.01
 
He encontrado otro hilo en el foro donde se habla del tema (http://www.clubdelphi.com/foros/showthread.php?t=2069) y donde se da la dirección donde descargar la versión 6.01 de las IBX: http://codecentral.borland.com/Item.aspx?id=17024

En cuanto pueda los bajo y lo pruebo.:D

maeyanes 12-09-2006 16:36:50

Actualiza tus componentes IBX a la versión 7.08: http://codecentral.borland.com/Item.aspx?id=20257

Tienes que registrarte en la página para poder bajarlos...



Saludos...

teracat 12-09-2006 16:52:53

Ibx 7.08
 
Muchas gracias. Voy a probarlos en cuanto pueda.

teracat 02-10-2006 17:31:34

Finalmente pude probarlo y tras varias pruebas conseguí el resultado esperado.

Muchas gracias por la ayuda! :D


La franja horaria es GMT +2. Ahora son las 12:35:46.

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