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)
那么,除非您自己保存了空格,否则值的末尾不应该有空格。lowvarchar(255)
值将返回给您,与您将其保存到表中时完全相同,无论char(255)
值是否正确填充空格,以便您始终获得包含255个字符的字符串
因此,我想说,如果您使用varchar
type,并且在将值保存到数据库中时不使用空格填充值,那么问题实际上在网格中,您无法使用SQL中的MGtrim()
或等效工具来解决它。最有可能的情况是,网格读取字段的定义,发现值的最大长度为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;