GARANTIR DESCONTO

Fórum Como saber o tamanho (size) de campo varchar Firebird? #457316

02/10/2013

0

Oi pessoal, eu de novo, estou aqui para tentar tirar uma dúvida sobre tamanhos de campo varchar. Estou fazendo uma aplicação em delphi que está quase pronta e estou precisando saber o tamanho dos campos Varchar do meu banco de forma automática para que eu não precise setar manualmente o tamanho dos meus Edits nos meus formulários que não são poucos. A ideia é fazer uma consulta diretamente no banco e retornar o tamanho de todos os campos (quantidade máxima de caracteres definida no create table) isso por tabela lógico. Ex. Fictício: SELECT SIZE(NOMEDOCAMPO) FROM TABELA. Ou se alguém souber de alguma forma de trazer essa informação utilizando o próprio delphi estou aberto a sugestões.

Grato.
Perinaldo Filho

Perinaldo Filho

Responder

Posts

02/10/2013

Deivison Melo

Perinaldo,

Recomendo o uso das funções:

CHAR_LENGTH() ou CHARACTER_LENGTH()


select CHAR_LENGTH('EMANOEL DEIVISON - FIREBIRD') QtdCaracteres1,
       CHARACTER_LENGTH('EMANOEL DEIVISON - DEVMEDIA') QtdCaracteres2
  FROM RDB$DATABASE


Com elas você poderá criar uma procedure no firebird para te ajudar nessa tarefa!

Recomendo o uso de domínios (DOMAIN) para criar os seus campos, com isso você
definirá os domínios desejados e caso precise alterar o tamanho ou até mesmo
precisão de algum campo, basta alterar os domínios.

Com eles sabemos exatamente a quantidade de caracteres em cada um dos campos
criados .


Exemplos:

Criando Domínios (DOMAIN)
CREATE DOMAIN SYSUSER AS VARCHAR(31) DEFAULT CURRENT_USER;


Alterando Domínios (DOMAIN)

ALTER DOMAIN SYSUSER TYPE VARCHAR(40);


Usando Domínios (DOMAIN)
CREATE TABLE LOANS (
LOAN_DATE DATE,
UPDATED_BY SYSUSER,
LOAN_FEE DECIMAL(15,2));


Pelo Delphi também da para ver exatamente e saber o tamanho
de cada um dos campos.

Caso tenha dúvida em fazer isso, por favor, sinalizar para ajudarmos da melhor forma possível!

Espero ter ajudado!!!

Abração e bons códigos!

Emanoel Deivison
Recife - PE




Responder

Gostei + 0

02/10/2013

Deivison Melo

Para pegar o tamanho do campo através do delphi use o comando: "Length".

Exemplo abaixo:

procedure TForm5.Button1Click(Sender: TObject);
begin
  ShowMessage('O Tamanho do campo é: '+ IntToStr(Length(DataSource1.DataSet.Fields[1].AsString)));
end;


Nesse exemplo eu peguei o tamanho do segundo campo do meu dataset (posição começa de "0" (zero)).

Abração e bons códigos!!!
Responder

Gostei + 0

02/10/2013

Deivison Melo

Se precisar redimencionar nos grid´s dá uma olhada no link abaixo:

[url]https://www.devmedia.com.br/redimensionar-colunas-dbgrid-delphi/18076[/url]

Abração e bons códigos!
Responder

Gostei + 0

03/10/2013

Perinaldo Filho

Talvez isso esteja mais perto do que eu preciso fazer. Vou testar aqui e aviso, porém, já de antemão pergunto, isso vai trazer o tamanho dos campos das tabelas ou o tamanho das strings contidas nesses campos? Lembrando que eu preciso pegar o tamanho do campo que foi definido no meu Create Table.

Ex:

CREATE TABLE USUARIO (
CODUSER INTEGER NOT NULL,
LOGIN VARCHAR(15),
SENHA VARCHAR(10),
STATUS CHAR(1));

Ao fazer isso que vc mostrou abaixo do campo LOGIN por exemplo, ele tem que retornar o tamanho "15", independentemente dos valores contidos nele.
Outra coisa, só posso fazer isso através de dataset ou posso por TSQLQuery tipo SQLQuery.fieldByName('LOGIN').ASString?

Para pegar o tamanho do campo através do delphi use o comando: "Length".

Exemplo abaixo:

procedure TForm5.Button1Click(Sender: TObject);
begin
  ShowMessage('O Tamanho do campo é: '+ IntToStr(Length(DataSource1.DataSet.Fields[1].AsString)));
end;


Nesse exemplo eu peguei o tamanho do segundo campo do meu dataset (posição começa de "0" (zero)).

Abração e bons códigos!!!
Responder

Gostei + 0

03/10/2013

Deivison Melo

Dá uma olhada nisso!


Através do Firebird:

[url]https://www.devmedia.com.br/quick-tips-consultando-as-tabela-e-campos-no-firebird-atraves-de-tabelas-de-sistemas/15066[/url]

Através do Delphi:

[url]https://www.devmedia.com.br/capturando-informacoes-do-dataset-em-conjunto-com-dbgrid-em-delphi/25086[/url]


Espero que essa dica complemente as demais!

Qualquer dúvida postar, que o ajudaremos!

Abração e bons códigos!


Responder

Gostei + 0

03/10/2013

Perinaldo Filho

Fiz o teste dessa forma e não funcionou:

var PSql : TSQLQuery;
SQLConnection : TSQLConnection;
begin
SQLConnection := TSQLConnection.Create(nil);
PSql := SQLConectarDatabase(SQLConnection);
PSql.SQL.Clear;
PSql.SQL.Text := 'SELECT * FROM CLIENTE';
PSql.Open;
ShowMessage('O Tamanho do campo é: '+ IntToStr(Length(PSql.FieldByName('NOME').AsString)));
PSql.Close;
SQLConnection.Connected := False;

Apareceu 32 só que o SIZE desse campo da minha tabela CLIENTE é 50. Verifiquei que 32 é a quantidade de caracteres que constam no meu primeiro registro dessa tabela.
Assim não serve, a ideia é justamente pegar o tamanho dos campos das tabelas pra travar o size dos edits de acordo com o size das tabelas justamente pra não permitir inserir nada além do que o banco suporte pra não dar truncation. Vou dar uma verificada nesses links que vc me passou pra ver se ajuda em algo.

Grato.
Responder

Gostei + 0

03/10/2013

Perinaldo Filho

Putz cara, você é mesmo F***!!!!!! Olhei os links e as duas formas servem pra mim, mas vou optar por criar uma procedure no banco onde eu passo o nome da tabela e ela me retorna o tamanho e nome dos campos. Já fiz aqui o SQL e está perfeito. Só criar uma procedure com isso!!


Muito Obrigado mais uma vez!!!!! Abraço!!
Responder

Gostei + 0

03/10/2013

Perinaldo Filho


Só mais uma dúvida, como faço essa procedure que criei ser executada no Firebird? Não está deixando eu compilar.

CREATE or ALTER PROCEDURE SP_RETORNATAMANHOCAMPOS(TAB VARCHAR(20))
RETURNS (CAMPO VARCHAR(15), TAMANHO INTEGER))
AS
BEGIN
SELECT
B.RDB$RELATION_NAME TABELA,
B.RDB$FIELD_NAME CAMPO,
A.RDB$FIELD_LENGTH TAMANHO
FROM RDB$FIELDS A,
RDB$RELATION_FIELDS B
WHERE
RDB$RELATION_NAME = :TAB
AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
END
Responder

Gostei + 0

03/10/2013

Perinaldo Filho

Percebi que tinha um parênteses ")" a mais, já tirei, mas agora está dando outro erro e não sei o que é. É com se não estivesse reconhecendo o END.

Erro:

can't format message 13:896 -- message file C:\Windows\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 17, column 1.
END.



Só mais uma dúvida, como faço essa procedure que criei ser executada no Firebird? Não está deixando eu compilar.

CREATE or ALTER PROCEDURE SP_RETORNATAMANHOCAMPOS(TAB VARCHAR(20))
RETURNS (CAMPO VARCHAR(15), TAMANHO INTEGER))
AS
BEGIN
SELECT
B.RDB$RELATION_NAME TABELA,
B.RDB$FIELD_NAME CAMPO,
A.RDB$FIELD_LENGTH TAMANHO
FROM RDB$FIELDS A,
RDB$RELATION_FIELDS B
WHERE
RDB$RELATION_NAME = :TAB
AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
END
Responder

Gostei + 0

03/10/2013

Deivison Melo

Boa tarde!

Veja se assim vai funcionar:

create or alter procedure PERINALDO (
    TAB varchar(60))
returns (
    TABELA char(31),
    CAMPO char(31),
    TAMANHO smallint)
as
BEGIN
  FOR
    SELECT
        B.RDB$RELATION_NAME TABELA,
        B.RDB$FIELD_NAME CAMPO,
        A.RDB$FIELD_LENGTH TAMANHO
    FROM RDB$FIELDS A,
         RDB$RELATION_FIELDS B
    WHERE RDB$RELATION_NAME = :TAB
      AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
    INTO :TABELA,
         :CAMPO,
         :TAMANHO
  DO
  BEGIN
    SUSPEND;
  END
END


Abração e bons códigos!

Responder

Gostei + 0

03/10/2013

Deivison Melo

Segue o DDL da PROCEDURE:

SET TERM ^ ;

create or alter procedure NEW_PROCEDURE (
    TAB varchar(60))
returns (
    TABELA char(31),
    CAMPO char(31),
    TAMANHO smallint)
as
BEGIN
  FOR
    SELECT
        B.RDB$RELATION_NAME TABELA,
        B.RDB$FIELD_NAME CAMPO,
        A.RDB$FIELD_LENGTH TAMANHO
    FROM RDB$FIELDS A,
         RDB$RELATION_FIELDS B
    WHERE RDB$RELATION_NAME = :TAB
      AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
    INTO :TABELA,
         :CAMPO,
         :TAMANHO
  DO
  BEGIN
    SUSPEND;
  END
END^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;


PS. Qualquer coisa faço pra vc na faculdade!

Se for o Perinaldo que estuda na Faculdade Santa Maria, já paguei cadeira com vc! rsrs

Abração e bons códigos!!
Responder

Gostei + 0

03/10/2013

Deivison Melo

Trocando os char´s por varchar´s...

Assim não completará com espaços vazios!!

SET TERM ^ ;
 
create or alter procedure NEW_PROCEDURE (
    TAB varchar(60))
returns (
    TABELA varchar(31),
    CAMPO varchar(31),
    TAMANHO smallint)
as
BEGIN
  FOR
    SELECT
        B.RDB$RELATION_NAME TABELA,
        B.RDB$FIELD_NAME CAMPO,
        A.RDB$FIELD_LENGTH TAMANHO
    FROM RDB$FIELDS A,
         RDB$RELATION_FIELDS B
    WHERE RDB$RELATION_NAME = :TAB
      AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
    INTO :TABELA,
         :CAMPO,
         :TAMANHO
  DO
  BEGIN
    SUSPEND;
  END
END^
 
SET TERM ; ^
 
GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;


Bom, acho que é isso aí!

Qualquer dúvida estamos por aqui garoto!

Abração e bons códigos!!
Responder

Gostei + 0

03/10/2013

Perinaldo Filho

Funcionou e consegui criar minha procedure no banco. Agora surgiu um novo problema. Estou tentando executar essa procedure no Delphi pra ter esse retorno mas não estou conseguindo. Tentei com TSQLStoredproc e com TSQLQuery e nada. Como eu vou pegar esse campo tamanho associado ao nome do campo pelo Delphi pra pegar o valor dele?

Trocando os char´s por varchar´s...

Assim não completará com espaços vazios!!

SET TERM ^ ;
 
create or alter procedure NEW_PROCEDURE (
    TAB varchar(60))
returns (
    TABELA varchar(31),
    CAMPO varchar(31),
    TAMANHO smallint)
as
BEGIN
  FOR
    SELECT
        B.RDB$RELATION_NAME TABELA,
        B.RDB$FIELD_NAME CAMPO,
        A.RDB$FIELD_LENGTH TAMANHO
    FROM RDB$FIELDS A,
         RDB$RELATION_FIELDS B
    WHERE RDB$RELATION_NAME = :TAB
      AND A.RDB$FIELD_NAME = B.RDB$FIELD_SOURCE
    INTO :TABELA,
         :CAMPO,
         :TAMANHO
  DO
  BEGIN
    SUSPEND;
  END
END^
 
SET TERM ; ^
 
GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;


Bom, acho que é isso aí!

Qualquer dúvida estamos por aqui garoto!

Abração e bons códigos!!
Responder

Gostei + 0

03/10/2013

Deivison Melo

Dá uma olhada aqui!

[url]http://marcosalles.wordpress.com/2011/06/29/executar-sored-procedures-com-parametros-utilizando-o-framework-dbxexpress-sem-dataset-delphi-2010-parte-iv/[/url]

Esse artigo também está bem legal!

[url]http://underpop.online.fr/b/banco-de-dados/dbexpress.pdf[/url]

Caso isso não solucionar o seu problema!

Posso fazer um exemplo e te mandar!

Mas é muito simples!!

PS. Aqui na Empresa não usamos Delphi nem firebird então fica complicado! [:)]

Abração e bons códigos!



Responder

Gostei + 0

03/10/2013

Deivison Melo

unit Unit8;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DBXFirebird, Data.FMTBcd,
  Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids, Data.DB, Datasnap.DBClient,
  Datasnap.Provider, Data.SqlExpr;

type
  TfrmConsultaProcedure = class(TForm)
    DBGrid1: TDBGrid;
    edtTabela: TEdit;
    btnTabela: TButton;
    SQLConnection1: TSQLConnection;
    SQLDataSet1: TSQLDataSet;
    DataSetProvider1: TDataSetProvider;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btnTabelaClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmConsultaProcedure: TfrmConsultaProcedure;

implementation

{$R *.dfm}

procedure TfrmConsultaProcedure.btnTabelaClick(Sender: TObject);
var
  strSQL: String;
begin
  strSQL:='';
  strSQL:=' select TABELA, CAMPO, TAMANHO '+
          '   from SP_RETORNA_TAM_CAMPOS(:TABELA) ';

  With ClientDataSet1 do
  begin
    CommandText:='';
    CommandText:=strSQL;
    Params.ParamByName('TABELA').AsString:=AnsiUpperCase(QuotedStr(edtTabela.Text));
    Open;
  end;
end;

procedure TfrmConsultaProcedure.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  SQLConnection1.Connected:=False;
end;

procedure TfrmConsultaProcedure.FormShow(Sender: TObject);
begin
  SQLConnection1.Connected:=True;
end;

end.


Para que fosse possível a consulta ser efetuada através do ClientDataSet
Tive que habilitar a property: poAllowCommand Em Options no meu
DataSetProvider.

Coloquei meu código do exemplo que fiz para orientá-lo!

Ao invés de usar o componente: "SQLStoredProc" eu usei o componente: "SQLDataSet"

Recomendo que use o componente: "SQLStoredProc" apenas para instruções
de insert e update.

Uma outra coisa que você deverá observar é a forma de consultar:

A instrunção ficará assim:

 select TABELA, CAMPO, TAMANHO
   from SP_RETORNA_TAM_CAMPOS(:TABELA)


Se fosse utilizar a mesma consulta no Oracle
ficaria assim:

 select NomeDoSchema.SP_RETORNA_TAM_CAMPOS(:TABELA)
   from sys.dual


Bom espero ter ajudado!

Abração e bons códigos!!


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar