Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Seleccionar un registro aleatorio en una tabla con un query!! (https://www.clubdelphi.com/foros/showthread.php?t=81639)

lobosito 02-12-2012 13:31:42

Seleccionar un registro aleatorio en una tabla con un query!!
 
Primero que nada hola a todos, esta es mi primer consulta y a que no he podido encontrar respuestas en otros hilos.

Me dieron un pequeño trabajo, en el que tengo que hacer un juego del ahorcado con acceso a BD, lo que estoy tratando de hacer es seleccionar un registro de manera aleatoria, mi tabla tiene 2 campos, una para el código (1,2,3,...,n), y otro donde va el término (Caballo, perro, etc.), lo que hice fue lo siguiente:

Código Delphi [-]
  // Encontrar el número de registros de la tabla
  Query1.SQL.Clear;
  Query1.SQL.Add('SELECT *');
  Query1.SQL.Add('FROM palabras.db');
  Query1.Active:=True;
  pos:=Query1.RowsAffected;
  Query1.Active:=False;
  // Encontrar un término de manera aleatoria
  Randomize;
  car:=random(pos)+1;
  car:=round(car);
  // Seleccionar el termino para adivinar y asignarlo a "a"
  Query1.SQL.Clear;
  Query1.SQL.Add('SELECT termino');
  Query1.SQL.Add('FROM palabras.db');
  Query1.SQL.Add('Where cod='+inttostr(car));
  Query1.Active:=True;
  a:=Query1.FieldValues['termino'];
  Query1.Active:=False;

pero siempre me devuelve el mismo registro el primero, como puedo hacer que realmente seleccione de manera aleatoria uno de mis registros en la tabla...

Agradezco cualquier ayuda, es algo que me tiene sin dormir y mi tiempo de entrega se acaba.

Casimiro Noteví 02-12-2012 13:50:34

Aunque no lo has puesto en el código, se supone que car será un integer.
Aquí te pego un ejemplo, para que veas como trabaja random


Código Delphi [-]
var
  float : single;
  int   : Integer;
  i     : Integer;

 begin
  // Get floating point random numbers in the range 0 <= Number < 1.0
  for i := 1 to 5 do
  begin
    float := Random;
    ShowMessage('float = '+FloatToStr(float));
  end;

  ShowMessage('');

  // Get an integer random number in the range 1..100
  for i := 1 to 5 do
  begin
    int := 1 + Random(100);    // The 100 value gives a range 0..99
    ShowMessage('int = '+IntToStr(int));
  end;
 end;

lobosito 02-12-2012 13:59:01

Cita:

Código Delphi [-]
  // Get an integer random number in the range 1..100
  for i := 1 to 5 do
  begin
    int := 1 + Random(100);    // The 100 value gives a range 0..99
    ShowMessage('int = '+IntToStr(int));
  end;
 end;

Perdón por no haberme explicado bien, conozco como funciona random, pero el problema radica en que siempre me devuelve el mismo término en mi consulta, es decir no está generando aleatorios, siempre me devuelve el número 1... y necesito que esto cambie porque solo necesito un registro.

Casimiro Noteví 02-12-2012 14:02:49

No sé qué base de datos estás usando, ¿has visto qué valor devuelve pos:=Query1.RowsAffected;?, seguramente siempre devuelve 1.
En lugar de:
select * from palabras.db
usa
select count(*) from palabras.db

Y no uses rowsaffected

Casimiro Noteví 02-12-2012 14:09:51

Algo así:
Código Delphi [-]
var
  iRegistros, iNumero : integer;
begin
  randomize;
    
  query.close;
  query.sql.text:='select count(*) from palabras.db';
  query.open;
  iRegistros := query.fields[0].asinteger;
  
  iNumero := random(iRegistros)+1;
    
  etc...


end;

lobosito 02-12-2012 14:24:16

Cita:

Empezado por Casimiro Notevi (Mensaje 451092)
No sé qué base de datos estás usando, ¿has visto qué valor devuelve pos:=Query1.RowsAffected;?, seguramente siempre devuelve 1.
En lugar de:
select * from palabras.db
usa
select count(*) from palabras.db

Y no uses rowsaffected

Gracias, probé antes con eso antes y no me dí cuenta de un error en mi bd, estoy usando paradox, ahora si me devuelve un registro aleatorio...muchas gracias, cuando termine subiré la aplicación para que puedan verla...muchísimas gracias nuevamente...

lobosito 02-12-2012 20:52:32

1 Archivos Adjunto(s)
Gracias a la ayuda, este es el código de mi Form1, en el Form2 está todo lo referente a cargar palabras a la BD, y en el Form3 todo lo referente al programa donde pongo el agradecimiento al foro y a Casimiro Notevi muchas gracias...

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ExtCtrls, StdCtrls, Mask, Buttons, DB, DBTables;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    A1: TMenuItem;
    Salir1: TMenuItem;
    NuevoJuego1: TMenuItem;
    Editarpalabras1: TMenuItem;
    Acercade1: TMenuItem;
    Panel1: TPanel;
    Image1: TImage;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit2: TEdit;
    Label3: TLabel;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    DataSource1: TDataSource;
    Query1: TQuery;
    Edit3: TEdit;
    procedure Edit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Salir1Click(Sender: TObject);
    procedure Editarpalabras1Click(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure Acercade1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  a:string;
  remp,aux,error:Integer;

implementation

uses Unit2, Unit3;

{$R *.dfm}

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  ter,car,enc:String;
  i,cont,intentos:Integer;
begin
  // Iniciación de remp
  remp:=0;
  // Pasar los caracteres ingresados al edit correspondiente
  Edit2.Text:=Edit2.Text+Edit1.Text;
  car:=Edit1.Text;
  Edit1.Text:='';
  // Asignacion de valores
  enc:=Edit3.Text;
  ter:=Edit2.Text;
  // Cambiar el caractér ingresado en el encriptado
  cont:=length(enc);
  for i:=1 to cont do
  begin
    if car[1]=a[i] then
    begin
      enc[i]:=car[1];
      remp:=remp+1
    end;
  end;
  Edit3.Text:=enc;
  if remp=0 then
  begin
    error:=error+1;
    //Ingresar el dibujo según error
    Image1.Picture.LoadFromFile('c:\ahorcado\pic\ahor'+IntToStr(error)+'.bmp');
  end;
  if error=6 then
  begin
    EditarPalabras1.Enabled:=True;
    SpeedButton2.Enabled:=True;
    Edit1.Enabled:=False;
    Application.MessageBox('Perdiste...que pena','Partida Perdida');
    Edit3.Text:=a;
  end;
  intentos:=length(Edit2.Text);
  if a=enc then
  begin
    EditarPalabras1.Enabled:=True;
    SpeedButton2.Enabled:=True;
    Edit1.Enabled:=False;
    Application.MessageBox('¡¡Ganaste!! Felicitaciones','Partida Ganada');
  end;
end;

procedure TForm1.Salir1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Editarpalabras1Click(Sender: TObject);
begin
  Form2.Showmodal;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  enc: string;
  i,car,pos,long: integer;
begin
  // Inicializar variables
  aux:=0;
  error:=0;
  remp:=0;
  // Encontrar el número de registros de la tabla
  Query1.SQL.Clear;
  Query1.SQL.Add('SELECT COUNT(*)');
  Query1.SQL.Add('FROM palabras.db');
  Query1.Active:=True;
  pos:=Query1.Fields[0].AsInteger;
  Query1.Active:=False;
  // Encontrar un término de manera aleatoria
  Randomize;
  car:=1+random(pos);
  car:=round(car);
  // Desactivar el botón de edición, habilitar los campos edit y dejarlos en blanco
  Edit2.Text:='';
  Edit3.Text:='';
  EditarPalabras1.Enabled:=False;
  SpeedButton2.Enabled:=False;
  Edit1.Enabled:=True;
  // Ingresar el 1º dibujo
  Image1.Picture.LoadFromFile('c:\ahorcado\pic\ahor0.bmp');
  // Seleccionar el termino para adivinar y asignarlo a "a"
  Query1.SQL.Clear;
  Query1.SQL.Add('SELECT termino');
  Query1.SQL.Add('FROM palabras.db');
  Query1.SQL.Add('Where cod='+inttostr(car));
  Query1.Active:=True;
  a:=Query1.FieldValues['termino'];
  Query1.Active:=False;
  // Colocar el término seleccionado en el edit3 pero encriptado
  long:=Length(a);
  for i:=1 to long do
  begin
    enc:=enc+'-';
  end;
  Edit3.Text:=enc;
end;

procedure TForm1.Acercade1Click(Sender: TObject);
begin
  Form3.ShowModal;
end;

end.

Casimiro Noteví 02-12-2012 20:59:37

Vaya, gracias, nunca vi a "Casimiro Notevi" en un "Acerca de..." :)


La franja horaria es GMT +2. Ahora son las 04:21:57.

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