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)
-   -   Crear una tabla en tiempo de ejecucion (https://www.clubdelphi.com/foros/showthread.php?t=85389)

gorsan 11-03-2014 23:49:52

Crear una tabla en tiempo de ejecucion
 
Hola.
¿Es posible crear una tabla IB en tiempo de ejecución? ¿Como?
He estado mirando por el foro antes de escribir y he visto algo sobre tablas temporales, etc. Pero yo lo que quiero es crear tablas persistentes pero en tiempo de ejecución del programa. El usuario proporciona el nombre de la tabla, por ejemplo, en un TEdit, y yo me ocupo de crear la tabla con unos campos predeterminados que seran siempre los mismos, si la tabla no existe. No se bien si hacerlo desde el lado del servidor, es decir, desde la BD mediante un store procedure que recoja el nombre como un parámetro de entrada; o hacerlo desde el lado cliente (Delphi 7) encapsulando desde un TIBDataSet por ejemplo.
¿Cómo puedo realizar esto?
Muchas gracias.

ecfisa 12-03-2014 05:39:41

Hola gorsan.

Te pongo un ejemplo desde el cliente usando TIBQuery y otro desde el servidor usando un stored procedure.

Cliente:
Código Delphi [-]
procedure TDataModule1.CreateTable(const TableName: string);
begin
 with TIBQuery.Create(nil) do
  try
    Close;
    Database:= IBDatabase1;
    Transaction:= IBTransaction1;
    SQL.Add('SELECT RDB$RELATION_NAME FROM RDB$RELATIONS');
    SQL.Add('WHERE RDB$VIEW_BLR IS NULL');
    SQL.Add('AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)');
    SQL.Add('AND RDB$RELATION_NAME = :PTABLE');
    ParamByName('PTABLE').AsString:= TableName;
    Open;
    if IsEmpty then
      with TIBQuery.Create(nil) do
      try
        Close;
        Database:= IBDatabase1;
        Transaction:= IBTransaction1;
        SQL.Add('CREATE TABLE '+ TableName + '(');
        SQL.Add('ID INTEGER, NOMBRE VARCHAR(30),');
        SQL.Add('etc, etc');
        SQL.Add(')');
        ExecSQL;
      finally
        Free;
      end
    else
      raise Exception.Create('Existe una tabla con ese nombre');
  finally
    Free;
    IBTransaction1.Commit;
  end;
end;

Servidor:
Código SQL [-]
SET TERM ^ ;

CREATE OR ALTER PROCEDURE SP_CREATE_TABLE (
    TABLENAME VARCHAR(100))
AS
DECLARE VARIABLE RESULT SMALLINT;
DECLARE VARIABLE SQL VARCHAR(300);
BEGIN
  SELECT COUNT(*)
  FROM RDB$RELATIONS
  WHERE RDB$VIEW_BLR IS NULL
  AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)
  AND RDB$RELATION_NAME = TRIM(:TABLENAME) INTO RESULT;

  IF (RESULT = 0) THEN
  BEGIN
    SQL= 'CREATE TABLE' || ' ' || TRIM(TABLENAME) || '('
         || 'ID INTEGER, NOMBRE VARCHAR(30),'
         || 'etc, etc);';
    EXECUTE STATEMENT SQL;
  END
  SUSPEND;
END^

SET TERM ; ^

Saludos :)

gorsan 12-03-2014 08:15:07

Muchas gracia ecfisa por tu contestación.
He probado ambas soluciones pero no me funcionan ninguna de las dos.
Por parte del ISQL se queja en la palabra OR y no compila.
Desde D7 se queja en el punto free del segundo finally y si lo elimino se queja en la sentencia del commit ambas con el mismo error de Class EAccessViolation. Lee de la dirección xxxxxxxxxxxxx.
El caso es que ambas rutinas tienen muy buena pinta pero me sucede eso.
Saludos

ecfisa 12-03-2014 17:48:57

Hola gorsan.

No sé que te puede estar sucediendo...Tal vez estes usando una versión menor de Firebird que la mía. Pero probé ambos códigos antes de publicarlos, nuevamente ahora y funcionan correctamente.

Saludos :)

Casimiro Notevi 12-03-2014 18:20:32

Cita:

Empezado por ecfisa (Mensaje 473615)
...

Escelente ^\||/


La franja horaria es GMT +2. Ahora son las 07:08:10.

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