Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-10-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Actualizar valores desde una consulta

Hola amigos, tengo un formulario de c++Builder donde he colocado los siguientes componentes: mysqlquery, dbgrid, mysqldatabase, datasource (creo que esos eran los nombres) he conseguido conectar todo y que haga una consulta con el mysqlquery y que me lo muestre en el dbgrid. Hasta ahí todo bien. El caso es que no se si puedo hacer que al modificar algo en el dbgrid se actualice en la base de datos. ¿alguien sabe? Estoy usando dac for mysql.
Responder Con Cita
  #2  
Antiguo 08-10-2015
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Dependerá un poco de los componentes en sí y de la consulta que hagas. Una consulta del tipo

Código SQL [-]
select columnas
from tabla
where condición

normalmente será actualizable (*). Esto quiere decir que bastará con que hagas el POST para que los cambios del DBGrid se reflejen en la base. El POST lo puedes hacer explícitamente, llamando al método correspondiente de mysqlquery, o implícitamente al momento de cambiarte de registro.

Si la consulta involucra enlaces a otras tablas (JOINs) entonces es posible que no puedas actualizar los datos de foma tan sencilla pues el componente necesita saber exactamente a qué registro de qué tabla pertenece el campo modificado.

Algunos conjuntos de componentes permiten especificar (en un componete auxilar o una propiedad) la consulta SQL necearia paa actualizar. En otros casos, tendrás que armar tú mismo la consulta UPDATE.

----------------------------
(*) Siempre y cuando columnas incluya una llave única de la tabla.

// Saludos
Responder Con Cita
  #3  
Antiguo 08-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

No he usado los componentes Microolap DAC for MySQL, pero por lo que pude mirar en la ayuda, son muy similares en el uso a los demás.
Siendo así, deberías asociar al TMySQLQuery un TMySQLUpdateSQL para poder realizar consultas actualizables.

Otra opción sería que optaras por usar el componente TMySQLDataset.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 08-10-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
He probado de dos maneras.
He colocado un componente TMySQLUpdateSQL y en el TMySQLQuery he puesto a este en la propiedad oportuna, luego en un botón hago esto:
Código:
mySQLUpdateSQL1->ModifySQL->Clear();
   mySQLUpdateSQL1->ModifySQL->Add(AnsiString().sprintf("UPDATE \"actor\""
                                                        "SET first_name = :%s"
                                                        "WHERE actor_id = :%s", EditName->Text, EditId->Text));
   mySQLUpdateSQL1->ModifySQL->Clear();
Y no hace absolutamente nada.
El segundo modo que he intentado es este:
Código:
   if(DBGrid1->DataSource->DataSet->Active)
      DBGrid1->Columns->operator [](1)->Field->Text="CUBO";
Y me suelta este error:
Cita:
MySQLQuery1: DataSet not in edit or insert mode.
No veo nada al respecto en las propiedades de ninguno de los componentes para ponerlo en modo edit o insert asi que ahi me quedo estancado.
Responder Con Cita
  #5  
Antiguo 08-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.


Para el primer caso tendrías que asociar el TMySQLUpdateSQL mediante la propiedad UpdateObject del TMySQLQuery y luego configurar en el primero las propiedades: DeleteSQL, InsertSQL y ModifySQL (al menos en los componentes como TUpdateSQL y TIBUpdateSQL funciona de ese modo).

En el segundo caso, el mensaje de error lo está indicando. Tenes que poner el DataSet en modo edición o inserción antes de intentar la actualización:
Código PHP:
  if(DBGrid1->DataSource->DataSet->Active) {
      
DBGrid1->DataSource->DataSet->Edit(); // o,  ...->Insert();
      
DBGrid1->Columns->operator [](1)->Field->Text="CUBO";
  } 

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 08-10-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Gracias amigo, ya he conseguido insertar, modificar, y eliminar de la base de datos pero ahora tengo otras dudas. Para eliminar o insertar una fila no tengo que ponerlo en modo Edit o Insert, para modificar si ¿a caso al eliminar o insertar una fila no estoy modificando la base de datos? es mas, si hago uso de Post() despues de insertar me guarda los cambios y sin el no me los guarda pero si lo uso despues de eliminar una fila me tira el error de que tengo que ponerla en Edit o Insert pero la fila ya aparece borrada permanentemente. Supongo que será algo que el creador de este componente ha querido hacer asi.
Otra duda, cuando elimino filas el indice es autonumerico y no queda correlativo ¿como puedo hacer que quede correlativo?
Y la última, me gustaria que el indice apareciera con el formato "00000000" pero es un entero y no muestra los ceros a la izquierda ¿Se puede hacer lo que deseo?
Responder Con Cita
  #7  
Antiguo 08-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

¿ Que componentes data-aware estas usando ? (DBGrid, DBEdit, etc.)
¿ Como estás realizando el borrado, inserción y modificacion ?
¿ Como y donde confirmas la acción realizada ?

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #8  
Antiguo 08-10-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
-Uso TEdits y DBGrid.
-El codigo que añade, edita, inserta, y elimina es este:
Código PHP:
void __fastcall TForm1::AddAVenta(void)
{
   
//Obtengo la cantidad del producto seleccionado
   
int stock DBGrid1->Columns->operator [](2)->Field->AsString.ToInt();

   
//Si la cantidad que tenemos es suficiente para la venta deseada...
   
if(stock -  EditCount->Text.ToInt() >= 0){
      
//Actualizo la cantidad en stock del producto
      
stock -= EditCount->Text.ToInt();

      
//Pongo la base de datos en modo edit
      
DBGrid1->DataSource->DataSet->Edit();

      
//Limpio la lista de modificaciones del componente
      
mySQLUpdateSQL1->ModifySQL->Clear();

      
//Envio la cadena que cambiará la cantidad de stock del producto en la tabla
      
mySQLUpdateSQL1->ModifySQL->Add(AnsiString().sprintf("UPDATE productos "
                                                           "SET Cantidad = %d "
                                                           "WHERE Codigo = %s"
,
                                                           
stock,
                                                           
EditId->Text));

      
//Indico que guarde los cambios
      
DBGrid1->DataSource->DataSet->Post();

      
//Limpio la lista de modificaciones del componente
      
mySQLUpdateSQL1->ModifySQL->Clear();

      
//Muestro la venta en el ListView que contiene la venta actual
      
TListItem *item ListView1->Items->Add();
      
item->Caption=EditId->Text;
      
item->SubItems->Add(EditName->Text);
      
item->SubItems->Add(EditCount->Text);
      
item->SubItems->Add(EditPVP->Text);
      
item->SubItems->Add(EditTotal->Text);

      
//Muestro el total a pagar hasta el momento
      
EditPagar->Text FormatFloat("0.00",EditPagar->Text.SubString(1,EditPagar->Text.Length() - 2).ToDouble() + EditTotal->Text.SubString(1,EditTotal->Text.Length() - 2).ToDouble()) + " €";
   }else{ 
//Si no queda suficiente producto en stock aviso y no hago nada
      
ShowMessage("No queda stock suficiente de este producto para vender.");
   }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::InsertarAStock(void)
{
   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->InsertSQL->Clear();

   
//Envio la cadena que cambiará la cantidad de stock del producto en la tabla
   
mySQLUpdateSQL1->InsertSQL->Add(AnsiString().sprintf("INSERT INTO productos (Articulo, Cantidad, Precio) "
                                                        "VALUES(\"%s\", %s, %.2lf)"
,
                                                        
EditName->Text,
                                                        
EditCount->Text,
                                                        
EditPVP->Text.SubString(1,EditPVP->Text.Length()-2).ToDouble()));

   
//Pongo la base de datos en modo edit
   
DBGrid1->DataSource->DataSet->Insert();

   
//Indico que guarde los cambios
   
DBGrid1->DataSource->DataSet->Post();

   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->InsertSQL->Clear();

}
//---------------------------------------------------------------------------

void __fastcall TForm1::EliminarDelStock(void)
{
   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->DeleteSQL->Clear();

   
//Envio la cadena que cambiará la cantidad de stock del producto en la tabla
   
mySQLUpdateSQL1->DeleteSQL->Add(AnsiString().sprintf("DELETE FROM productos WHERE Codigo = %s",EditId->Text));
   
   
//Pongo la base de datos en modo edit
   
DBGrid1->DataSource->DataSet->Delete();

   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->DeleteSQL->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ModificarProducto(void)
{
   
//Pongo la base de datos en modo edit
   
DBGrid1->DataSource->DataSet->Edit();

   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->ModifySQL->Clear();

   
//Envio la cadena que cambiará la cantidad de stock del producto en la tabla
   
mySQLUpdateSQL1->ModifySQL->Add(AnsiString().sprintf("UPDATE productos "
                                                        "SET Articulo = \'%s\', "
                                                        "Cantidad = %s, "
                                                        "Precio = %.2lf "
                                                        "WHERE Codigo = %s"
,
                                                        
EditName->Text,
                                                        
EditCount->Text,
                                                        
EditPVP->Text.SubString(1,EditPVP->Text.Length()-2).ToDouble(),
                                                        
EditId->Text));

   
mySQLQuery1->Active true;

   
//Indico que guarde los cambios
   
DBGrid1->DataSource->DataSet->Post();

   
//Limpio la lista de modificaciones del componente
   
mySQLUpdateSQL1->ModifySQL->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
   switch(
RadioGroup1->ItemIndex){
      case 
0//Modo Venta
         
AddAVenta();
         break;

      case 
1//Insertar producto
         
InsertarAStock();
         break;

      case 
2//Eliminar producto
         
EliminarDelStock();
         break;

      case 
3//Modificar producto
         
ModificarProducto();
         break;
   }

Se que tendrá fallos tremendos que yo no veo pero que alguien que sepa del tema ya me estaria tirando una chancla jajaja.
-Y confirmar no confirmo nada porque no se como se haria.

Otra cosa mas, todo esto está muy bien pero si yo crease una aplicacion que usase esta base de datos ¿como haria para que al instalar otra persona en su pc mi aplicacion ya leyese la misma base de datos? En este caso me basta con que me la cree con la tabla que tengo y las columnas que tiene la tabla pero me interesa saberlo ya que he leido que no es como con SQLite, que yo cogia el archivo de la base de datos y lo colocaba junto con la dll y mi aplicacion y a tirar. He leido que no es un archivo, es mas, he mirado en las rutas que proponen por internet y el archivo no aparece, ni siquiera aparece nada con el nombre de la tabla o base de datos. Entonces me interesaria saber como mudar la base de datos de un pc a otro y como crear con estos componentes una base de datos y una tabla ya que lo tuve que hacer desde la consola usando comandos de mysql porque no vi la manera de hacerlo desde los componentes.
Responder Con Cita
  #9  
Antiguo 08-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

Usando Edits, básicamente las acciones son,
Código PHP:
// INSERTAR
void __fastcall TForm1::btnInsertClick(TObject *Sender)
{
  
DBGrid1->DataSource->DataSet->Insert();
}

// EDITAR
void __fastcall TForm1::btnEditClick(TObject *Sender)
{
  
DBGrid1->DataSource->DataSet->Edit();
}

// BORRAR
void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
  
DBGrid1->DataSource->DataSet->Delete();
}

// CANCELAR
void __fastcall TForm1::btnCancelClick(TObject *Sender)
{
  
DBGrid1->DataSource->DataSet->Cancel();
}

// GUARDAR
void __fastcall TForm1::btnPostClick(TObject *Sender)
{
  
TDataSetDS static_cast<TDataSet*>(DBGrid1->DataSource->DataSet);
  if (
DS->State == dsInsert || DS->State == dsEdit) {
    
DS->FieldByName("CAMPO1")->Value Edit1->Text;
    
DS->FieldByName("CAMPO2")->Value Edit2->Text;
    
DS->FieldByName("CAMPO3")->Value Edit3->Text;
    ...
    
DS->Post();
  }

pero te podes ahorrar todos esos botones usando el componente TDBNavigator.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #10  
Antiguo 09-10-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Tanto con los botones y codigos que me indicas como con el DBNavigator da error. Dice algo asi como que no hay stament dataset o algo asi era. Por eso lo hice yo de esa manera.

Otra cosa, aun no se como crear la base de datos en runtime pero teniendo la base de datos creada si he podido ver como crear la tabla. Uso este codigo:
Código PHP:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   
//Primero tengo que crear la base de datos en ejecucion si no existe
   //Aqui...

   
mySQLTable1->TableName "Productos";
   
//Luego creo la tabla si no existe
   
if(!mySQLTable1->Exists){
      
// El componente Table no debe estar activo
      
mySQLTable1->Active false;

      
// Primero, describo el tipo de tabla le asigno un nombre
      
mySQLTable1->Database->DatabaseName "stocks";
      
mySQLTable1->TableName "Productos";

      
// Describo los campos en la tabla
      
mySQLTable1->FieldDefs->Clear();
      
TFieldDef *pFieldDef mySQLTable1->FieldDefs->AddFieldDef();
      
pFieldDef->Name "Codigo";
      
pFieldDef->DataType ftLargeint;
      
pFieldDef->Required true;

      
pFieldDef mySQLTable1->FieldDefs->AddFieldDef();
      
pFieldDef->Name "Articulo";
      
pFieldDef->DataType ftString;
      
pFieldDef->Size 50;
      
pFieldDef->Required true;

      
pFieldDef mySQLTable1->FieldDefs->AddFieldDef();
      
pFieldDef->Name "Cantidad";
      
pFieldDef->DataType ftLargeint;
      
pFieldDef->Required true;

      
pFieldDef mySQLTable1->FieldDefs->AddFieldDef();
      
pFieldDef->Name "Precio";
      
pFieldDef->DataType ftFloat;
      
pFieldDef->Required true;

      
// Describo algunos indexes
      
mySQLTable1->IndexDefs->Clear();
      
TIndexDef *pIndexDef mySQLTable1->IndexDefs->AddIndexDef();
      
pIndexDef->Name "CodIndexDef";
      
pIndexDef->Fields "Codigo";
      
pIndexDef->Options.Contains(ixPrimary ixUnique);

      
// Llamo al metodo CreateTable para crear la tabla
      
mySQLTable1->CreateTable();
   }

   
//mySQLQuery1->ExecSQL();
   //mySQLDatabase1->DatabaseName = "stocks";
   
mySQLDatabase1->Connected true;
   
mySQLQuery1->SQL->Clear();
   
mySQLQuery1->SQL->Add("SELECT * FROM productos");
   
mySQLQuery1->Active true;

El problema es que no se parece en nada a lo que creo desde la consola con esto:
Código:
CREATE TABLE IF NOT EXISTS Productos (
Codigo mediumint(8) unsigned default null auto_increment, 
Articulo varchar(50) not null,
Cantidad int(10) unsigned not null, 
Precio double unsigned not null,
PRIMARY KEY (Codigo)
);
Con el primero no he podido ver aun como autoincrementar el indice Codigo, los tamaños de los campos son diferentes, y los tipos de variables.
Con este ultimo obtengo esto:

Código:
+----------+-----------------------+------+-----+---------+----------------+
| Field    | Type                  | Null | Key | Default | Extra          |
+----------+-----------------------+------+-----+---------+----------------+
| Codigo   | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| Articulo | varchar(50)           | NO   |     | NULL    |                |
| Cantidad | int(10) unsigned      | NO   |     | NULL    |                |
| Precio   | double unsigned       | NO   |     | NULL    |                |
+----------+-----------------------+------+-----+---------+----------------+
Mientras que con el codigo primero obtengo esto:
Código:
+----------+------------+------+-----+---------+-------+
| Field    | Type       | Null | Key | Default | Extra |
+----------+------------+------+-----+---------+-------+
| Codigo   | bigint(20) | NO   | MUL | NULL    |       |
| Articulo | char(50)   | NO   |     | NULL    |       |
| Cantidad | bigint(20) | NO   |     | NULL    |       |
| Precio   | double     | NO   |     | NULL    |       |
+----------+------------+------+-----+---------+-------+
¿Como hago para que el primer codigo me lo cree igual que el otro? Ni siquiera puedo poner el auto-incremento.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Consulta con valores null Luis M. Firebird e Interbase 15 11-03-2012 00:06:56
Como obtener valores de una consulta Alexandro SQL 5 26-02-2009 22:21:22
Consulta de valores consecutivos Guillermosalva SQL 5 27-07-2007 08:49:15
Consulta entre valores rruffino Conexión con bases de datos 1 11-05-2007 03:25:34
Campos de consulta con valores NAN ElDuc SQL 1 12-09-2005 10:28:59


La franja horaria es GMT +2. Ahora son las 04:37:11.


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
Copyright 1996-2007 Club Delphi