Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在SQL中裁剪字段长度,使其不会占用DBGrid的所有空间?_Mysql_Delphi_Firebird_Delphi 2006 - Fatal编程技术网

Mysql 如何在SQL中裁剪字段长度,使其不会占用DBGrid的所有空间?

Mysql 如何在SQL中裁剪字段长度,使其不会占用DBGrid的所有空间?,mysql,delphi,firebird,delphi-2006,Mysql,Delphi,Firebird,Delphi 2006,假设我有这张桌子: name varchar(255), quantity integer, value float 当我使用此代码时: select left(name, 99), quantity, value from table; 但是我在dbgrid的第一列和其他两个字段中都有255个空格(我所说的空格是指宽度-长度,而不是真正的空格字符),除非我使用滚动条,我的目标是使滚动条不再必要 我如何正确实现这个目标?我使用Firebird和MySQL。 我

假设我有这张桌子:

name        varchar(255),
quantity    integer,
value       float
当我使用此代码时:

select left(name, 99), quantity, value from table;
但是我在
dbgrid
的第一列和其他两个字段中都有255个空格(我所说的空格是指宽度-长度,而不是真正的空格字符),除非我使用滚动条,我的目标是使滚动条不再必要

我如何正确实现这个目标?我使用Firebird和MySQL。

我不能用pascal代码来实现这一点,也不能在table组件的Fields对象上定义它,因为这些代码来自许多表,因为这是一个报表生成器,第一个字段并不总是相同的,对于每个报表,我必须使用不同的SQL代码


请大家在回答之前阅读所有问题。前3个答案哪里错了,因为他们没有考虑到最后一段写的内容 >/p>< p>由于您在“代码”> tfield <代码>级别或您的Delphi代码中不能做到这一点,可以使用“<代码>三”(<代码> >或<代码>左())/代码>,根据您正在使用的数据库,在列中删除您不想显示的空白空间:

例如,在许多SQL方言中,您可以使用如下内容:

SELECT Col1, Col2, Trim(Col3) as Col3 FROM yourtable 
WHERE somecondition
有些人允许这样做:

SELECT Col1, Col2, Left(Col3, MaxCharWidthAllowed) as Col3 FROM yourtable 
WHERE somecondition

作为快速测试(我没有FB,但是有SQL Server 2008,所以我使用了它),我在SQL Server Management Studio中创建了以下测试数据:

然后,我创建了一个新的D2007 VCL表单应用程序,并执行了以下步骤:

  • 在表单(
    ADOConnection1
    )上删除了一个
    TADOConnection
    ),并设置与上述测试数据的连接字符串
  • 在表单上删除了两个
    TADOQuery
    组件(
    adokery1
    adokery2
    ),并将它们的
    Connection
    属性设置为
    ADOConnection1
  • 在表单上删除了两个
    TDataSource
    组件(
    DataSource1
    DataSource2
    ),并将它们的
    DataSet
    属性连接到匹配的
    ADOQuery1
    ADOQuery2
  • 删除了两个
    TDBGrid
    组件(
    DBGrid1
    DBGrid2
    ),并将它们的
    DataSource
    属性设置为匹配的
    DataSource1
    DataSource2
  • SELECT*fromtest
    添加到
    ADOQuery1
  • 添加了
    选择子字符串(itemname,1,30)作为测试中的itemname,quantity,value
    作为
    ADOQuery2
    SQL
    30
    的长度被任意选择为一个足够小的值,以显示相当小的列宽
  • ADOConnection1.Connected
    设置为
    True
    ,并将
    TADOQuery.Active
    属性设置为
    True
上面生成了此输出(在设计时,从未编译或运行应用程序),顶部网格为
DBGrid1


如您所见,在使用SQL中的
子字符串连接到
ADOQuery2
DBGrid2
中,第一列的大小正确为30个字符宽。

如果列类型确实是
varchar(255)
而不是
char(255)
那么,除非您自己保存了空格,否则值的末尾不应该有空格。low
varchar(255)
值将返回给您,与您将其保存到表中时完全相同,无论
char(255)
值是否正确填充空格,以便您始终获得包含255个字符的字符串


因此,我想说,如果您使用
varchar
type,并且在将值保存到数据库中时不使用空格填充值,那么问题实际上在网格中,您无法使用SQL中的MG
trim()
或等效工具来解决它。最有可能的情况是,网格读取字段的定义,发现值的最大长度为255个字符,并相应地设置列宽。因此,解决方案实际上是手动设置列宽或使用column的
ApplyBestFit
方法(如果有)。

有两种方法可以限制DBGrid中显示的字段的长度,而不会改变数据库中的数据。一个是通过设置字段的DisplayWidth,另一个是设置网格列的宽度

您可以在查询的“打开后”事件中设置DisplayWidth。该示例针对ZeosLib,并假设第一个字段是要限制的字段。这需要添加到每个查询中

procedure TForm1.ZQuery1AfterOpen(DataSet: TDataSet);
begin
  DataSet.Fields[0].DisplayWidth := 99;
end;
或者使用过程在打开查询后设置DBGrid列宽。此示例允许您指定列以及宽度

procedure TForm1.SetColWidth(c,w: integer);
begin
  if DBGrid1.Columns.Count > c then
    DBGrid1.Columns[c].Width := w;
end;

更新:

Delphi将varchar字段的长度作为显示长度的默认值。varchar(255)=Displaylength=255

我可以用“SQL”来改变这种行为吗 如果结果只有99个字符长,则长度varchar(255)=255,显示长度=255

比较一下
允许的:

  • Sql应该快速交付数据集(而不是报表的设计)
  • 对于每个varchar字段的每个表,必须设置额外的SQL语句
    (xname,99)
  • 我能看到被截断的(可能是重要的)信息吗?从来没有
wy不允许:

Columns[index].Width = 99;
  • 更容易设计报告
  • 更容易选择SQL语句:
    从表中选择名称、数量和值
  • 用鼠标简单展开列以查看隐藏信息
  • 良好的设计:DBGrid的列大小应该是一次至少可以看到2列
程序应接管设计。

我不能用pascal代码来实现这一点,也不能在table组件的Fields对象上定义它,因为该代码来自许多表,因为这是一个repor
select left(name,99), quantity, value from table;
Columns[index].Width = 99;
   Query1.Close;
   Query1.SQL.Clear;
   Query1.SQL.Add ('select name, quantity, value from table');
   Query1.Active: = true;
   Columns[index].Width := 99;
unit FBAuto;
{
~Zarko Gajic
About Delphi Programing
http://delphi.about.com
customized 2013
moskito-x software
}

interface

uses
  Math,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, Grids, DBGrids, ExtCtrls, StdCtrls, ZAbstractRODataset,
  ZAbstractDataset, ZDataset, ZConnection;

type
  TAutoColumnWidth = record
    Index : integer;
    Width : integer;
  end;

  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    DataSource1: TDataSource;
    CBuseMe: TCheckBox;
    DBGrid2: TDBGrid;
    ZQuery2: TZQuery;
    DataSource2: TDataSource;
    IntegerField1: TIntegerField;
    StringField1: TStringField;
    procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure CBuseMeClick(Sender: TObject);
  private
    { Private declarations }
    procedure SetFit;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  AutoColumnWidth : TAutoColumnWidth;
  useMe :Boolean;

procedure TForm1.SetFit;
var
  i:integer;
begin
  if NOT CBuseMe.Checked then begin
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
     if DBGrid1.Columns[i].Field.Size > 300 then
        DBGrid1.Columns[i].Width := DBGrid1.Columns[i].Field.Size;
  end;
  end else begin
  useMe:=true;
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
  AutoColumnWidth.Index:=-1;
  if DBGrid1.Columns[i].Field.DisplayWidth > 200 then  AutoColumnWidth.Index:=i;
     if AutoColumnWidth.Index > -1 then begin
        AutoColumnWidth.Width := -1;
        DBGrid1.Repaint;
        DBGrid1.Columns[AutoColumnWidth.Index].Width := AutoColumnWidth.Width+ 5;
     end;
  end;
  useMe:=false;
  end;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
ZQuery1.Active:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AutoColumnWidth.Index := -1;
  AutoColumnWidth.Width := -1;
  useMe:=false;
end;

procedure TForm1.CBuseMeClick(Sender: TObject);
begin
  setFit;
end;

procedure TForm1.DBGrid1DrawColumnCell(
  Sender: TObject;
  const Rect: TRect;
  DataCol: Integer;
  Column: TColumn;
  State: TGridDrawState);
begin
  if useMe then begin
   if DataCol = AutoColumnWidth.Index then
   begin
    if Assigned(Column.Field) then
    begin
      AutoColumnWidth.Width := Max(AutoColumnWidth.Width, DBGrid1.Canvas.TextWidth(Column.Field.DisplayText));
    end;
   end;
  end;
end;

end.
if DBGrid1.Columns[i].Field.DisplayWidth > 200 then  AutoColumnWidth.Index:=i;