怎样解决三层中的主从表问题,望各位不啬赐教!急!急!! (顶者有分!另开贴400大洋给解决问题的高手)(100分)

  • 主题发起人 主题发起人 jong
  • 开始时间 开始时间
J

jong

Unregistered / Unconfirmed
GUEST, unregistred user!
我在远程数模中建立主从关系:
A、主表数据集:qymaster,SqlText为‘Select * from Master’;数据源为DpMD,其中属性poFetchdetailsOnDemand为True,poAllowCommandText为True。
B、从表数据集(TADODataSet):QyDetail,CommandText为‘Select * from detail where ID=:ID’,DataSorurce设为‘dsmaster’,MasterFields为‘ID’。
在客户端新建两个TClientDataSet:
1、主表cdsMaster:数据源为DpMD。添加所有字段
2、从表cdsDetail:DataSetField为cdsDetail
但我新增时出现‘Insert语句与Column Foreign key约束‘Fk_Detail_Master’冲突,该冲突发生于数据库'Dataset1',表‘MASTER’,column 'ID'’
新增时ID并没有重复!
我试过很多方法都不行,因初学三层,特向熟悉三层的朋友请教解决主从关系问题。
最好能发源码例子,分不够可开另加三百分。望各位不啬赐教!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3438385
 
主从关系中应先更新主表,然后再更新从表。
 
TO:kaida
在三层中怎样控制先更新主表再更新从表呢。ApplyUpdates(0)默认好像是先更新从表。
 
建议不要用嵌套表
<delphi 6开发人员指南>中有示例,可以在一个事务中更新N个clientdataset。
 
因为要用到CDS数据文件的问题,主从表保存到一个本地CDS文件中好做一点,
所以用到巢状数据库。但新增ApplyUpdates(0)后老是出外键出错的问题,
哪位大侠有没有办法帮帮忙,此类问题如何解决??谢谢!!
 
建议你最好不要,最好使用SQL 写主从表的连接。我都是这样写三层的,效果不错。
 
谢谢 蓝叶菱的回答
>>这个最好使用建立一个接口函数,自己使用SQL 写。不建议使用DATASOURCE进行连接。否则不好处理,冲突频繁。
建立接口函数,该怎样建立呢?有没相应的例程给小弟学习一下。因这个问题已经困惑了好久了。2841656@163.com
 
相信我没有错的,我做的系统都卖钱了,主从表就是这样解决的。
 
在两层的系统里面我也是用SQL和事务来解决主从关系,而不是用DataSource连接主从关系的,在三层里面巢状数据库要怎么做呢,因我的表也有主—从—从的关系,巢状cds可以一起保存三个文件。写远程过程、函数会不会太麻烦了。
 
同意 蓝叶菱,最好自己写,你要对ADO很熟还好,不熟,系统又复杂,有的你玩了
 
其实用楼主这种处理方法是很好用的,不过要处理好才行
新增记录:新增主表,再增从表,从表增加的时候要将关联字段值写上,且不允许再修改
删除记录:先删除从表,再删除主表
提交只要提交主表就行了
 
To:stuwe
我在http://www.delphibbs.com/delphibbs/dispq.asp?lid=3438385
简单的例程。但就是会出现外键冲突。我在数据库中主从表设置了主从级联。
 
数据库中不要设置主从级联就应该没问题了
 
1 在服务器端不必设主从关系
2 在客户端设设主从关系
从表TClientDataSet
MasterFields = 'CategoryID'
MasterSource = DataSource1
3 从表的外键值不必赋值
把下面存成 Unit1.dfm
object Form1: TForm1
Left = 192
Top = 107
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 160
Top = 48
Width = 513
Height = 113
DataSource = DataSource1
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object DBGrid2: TDBGrid
Left = 160
Top = 240
Width = 513
Height = 169
DataSource = DataSource2
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object Button1: TButton
Left = 16
Top = 112
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 2
OnClick = Button1Click
end
object Button2: TButton
Left = 64
Top = 336
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 3
OnClick = Button2Click
end
object DBNavigator1: TDBNavigator
Left = 176
Top = 16
Width = 240
Height = 25
DataSource = DataSource1
TabOrder = 4
end
object DBNavigator2: TDBNavigator
Left = 248
Top = 208
Width = 240
Height = 25
DataSource = DataSource2
TabOrder = 5
end
object ADOConnection1: TADOConnection
Connected = True
ConnectionString =
'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initi' +
'al Catalog=Northwind;Data Source=127.0.0.1'
LoginPrompt = False
Provider = 'SQLOLEDB.1'
Left = 96
Top = 72
end
object DataSetProvider1: TDataSetProvider
DataSet = ADOQuery1
Options = [poAllowCommandText]
Left = 152
Top = 120
end
object DataSetProvider2: TDataSetProvider
DataSet = ADOQuery2
Options = [poAllowCommandText]
Left = 168
Top = 176
end
object ClientDataSet1: TClientDataSet
Active = True
Aggregates = <>
AggregatesActive = True
CommandText =
'SELECT CategoryID, CategoryName, Description, Picture FROM Categ' +
'ories'
Params = <>
ProviderName = 'DataSetProvider1'
Left = 256
Top = 120
end
object ClientDataSet2: TClientDataSet
Active = True
Aggregates = <>
CommandText = 'SELECT * FROM Products'
IndexFieldNames = 'CategoryID'
MasterFields = 'CategoryID'
MasterSource = DataSource1
PacketRecords = 0
Params = <>
ProviderName = 'DataSetProvider2'
Left = 256
Top = 176
end
object ADOQuery1: TADOQuery
Connection = ADOConnection1
Parameters = <>
Left = 96
Top = 120
end
object ADOQuery2: TADOQuery
Connection = ADOConnection1
Parameters = <>
Left = 96
Top = 176
end
object DataSource1: TDataSource
DataSet = ClientDataSet1
Left = 296
Top = 128
end
object DataSource2: TDataSource
DataSet = ClientDataSet2
Left = 304
Top = 184
end
end
把下面存成 Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, StdCtrls, Grids, DBGrids, ADODB, DBClient, Provider,
ExtCtrls, DBCtrls;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
DataSetProvider1: TDataSetProvider;
DataSetProvider2: TDataSetProvider;
ClientDataSet1: TClientDataSet;
ClientDataSet2: TClientDataSet;
ADOQuery1: TADOQuery;
ADOQuery2: TADOQuery;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
Button1: TButton;
DataSource1: TDataSource;
DataSource2: TDataSource;
Button2: TButton;
DBNavigator1: TDBNavigator;
DBNavigator2: TDBNavigator;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.ApplyUpdates(0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ClientDataSet2.ApplyUpdates(0);
end;

end.
 
TPersonBasVO = class(TDataTransferObject)
private
FDno: string;
//单位编号
FSdno: String;
//售电点编号
FSecno: String;
//区域编号
FYhh: string;
//用户号
FYhbm: String;
//用户编码
FDjbm: String;
//多级编码
FDwdjbm: String;
//电网多级编码
FYhm: string;
//用户名
FAddr: String;//地址
FDeptName:string;//单位名称
FTel: String;
//电话
FPbbz: Integer;
//配表标志
FXgcs: Integer;
//限购次数
FGdsx: Integer;
//购电上限
Fstatues: Boolean;
//状态
FKhrq: TDateTime;
//开户日期
FFtlb: String;//分摊类别
FFtb: Real;//分摊比
FFtzp: Real;
//分摊电价
Fftlbname: String;
//分摊名称
published
Property PK_Dno : String index 0 Read FDno Write FDno;
Property PK_Sdno : String index 1 Read FSdno Write FSdno;
Property PK_Secno : String index 2 Read FSecno Write FSecno;
Property PK_Yhh : String index 3 Read FYhh Write FYhh;
Property Yhbm : String index 4 Read FYhbm Write FYhbm;
Property Djbm : String index 5 Read FDjbm Write FDjbm;
Property Dwdjbm : String index 6 Read FDwdjbm Write FDwdjbm;
Property Yhm : String index 7 Read FYhm Write FYhm;
Property Addr : String index 8 Read FAddr Write FAddr;
Property DeptName : String index 9 Read FDeptName Write FDeptName;
Property Tel : String index 10 Read FTel Write FTel;
Property Pbbz : Integer index 11 Read FPbbz Write FPbbz;
Property Xgcs : Integer index 12 Read FXgcs Write FXgcs;
Property Gdsx : Integer index 13 Read FGdsx Write FGdsx;
Property statues : Boolean index 14 Read Fstatues Write Fstatues;
Property Khrq : TDateTime index 15 Read FKhrq Write FKhrq;
Property Ftlb : String index 16 Read FFtlb Write FFtlb;
Property Ftb : Real index 17 Read FFtb Write FFtb;
Property Ftzp : Real index 18 Read FFtzp Write FFtzp;
Property ftlbname : String index 19 Read Fftlbname Write Fftlbname;
public
constructor Create;
end;

TCardBasVO = class(TDataTransferObject)
public
FYhh: string;
//用户号
FYhcard: String;
//用户卡号
FMid: String;
//表类型
FModel: String;
//表型号
FMeter_no: String;
//表编号
FMorder: Integer;
//表顺序号
FPno: String;// 价格编号
FBds:do
uble;
//表底度
FCnst: Integer;
//脉冲常数
FBb: Integer;
//变比
FGmodel: String;
//型号规格
FMdate: TDateTime;
//建档日期
FFtlb: String;//分摊类别
FFtb: Real;//分摊比
published
Property PK_Yhh : String index 0 Read FYhh Write FYhh;
Property PK_Yhcard : String index 1 Read FYhcard Write FYhcard;
Property Mid : String index 2 Read FMid Write FMid;
Property Model : String index 3 Read FModel Write FModel;
Property Meter_no : String index 4 Read FMeter_no Write FMeter_no;
Property PK_Morder : Integer index 5 Read FMorder Write FMorder;
Property Pno : String index 6 Read FPno Write FPno;
Property Bds :do
uble index 7 Read FBds Write FBds;
Property Cnst : Integer index 8 Read FCnst Write FCnst;
Property Bb : Integer index 9 Read FBb Write FBb;
Property Gmodel : String index 10 Read FGmodel Write FGmodel;
Property Mdate : TDateTime index 11 Read FMdate Write FMdate;
Property Ftlb : String index 12 Read FFtlb Write FFtlb;
Property Ftb : Real index 13 Read FFtb Write FFtb;
public
constructor Create;
end;

//明细表:
TDetail = class(TDataTransferObject)
public
person: TPersonBasVO;
card: TCardBasVO;
published
Property Fperson : TPersonBasVO index 0 Read person Write person;
Property Fcard : TCardBasVO index 1 Read card Write card;
public
constructor Create(tmpPer: TPersonBasVO;
tmpCard: TCardBasVO);
end;

//明细表测试
{
personVO.PK_Dno := '001';
Detail := TDetail.Create(personVO, CardVO);
rdmDS.SelectRDMDS(Detail, ClientDataSet2);
}
我的SQL是根据关系映射的。支持OO,多表,视图关联之内,解决很方便,喜欢的话和我联系。
 
感觉能从底层控制SQL语句是比较好的。
一个比较简单的O/P MAPING,有兴趣你可以扩充它哟。
主要的核心代码如下,DAOAdapter根据VO生成SQL语句。支持OO。DAO模式,不用我多介绍了吧。不了解可以去看看JAVA。另外通过AOP对 DAO模板进行拦截,依赖注入与控制反转,程序运行时,从一个数据库连接池获得一个连接,注入模板中。彻底实现数据库的移植问题。有兴趣可以和我讨论。
interface
Uses
Classes, DB, Contnrs, SysUtils, uDataTransferObject;

type
TDAOAdapter = class(TPersistent)
public
function GetFldName(tmpFld: String): String;
function IsKeyFld(tmpFld: String): Boolean;
function getKeySQLString(Const pTO: TDataTransferObject): String;
function getMaxCountString(Const pTO: TDataTransferObject): String;
function getSearchSQLString(Const pTO: TDataTransferObject): String;
function getInsertSQLString(Const pTO: TDataTransferObject): String;
function getUpdateSQLString(Const pTO: TDataTransferObject): String;
function getDeleteSQLString(Const pTO: TDataTransferObject): String;
constructor Create;
destructor Destroy;
override;
end;

implementation
uses uMPropList, TypInfo, dialogs;
constructor TDAOAdapter.Create;
begin
inherited Create;
end;

function TDAOAdapter.GetFldName(tmpFld: String): String;
begin
if Uppercase(copy(tmpFld, 1, 3)) = 'PK_' then
Result := Copy(tmpFld, 4, length(tmpFld))
else
if Uppercase(tmpFld) = 'TBNAME' then
Result := ''
else
Result := tmpFld;
end;

function TDAOAdapter.IsKeyFld(tmpFld: String): Boolean;
begin
if Uppercase(copy(tmpFld, 1, 3)) = 'PK_' then
Result := True
else
Result := False;
end;

function TDAOAdapter.getKeySQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpFid, tmpTbname: String;
tmpPropList: TMPropList;
filter: string;
begin
tmpSQL := 'select count(*) as mySum from ';
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := tmpSQL + tmpTbname+ ' where 1=1 and ';

for i:=0 to tmpPropList.PropCount-1do
begin
if (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true) then
filter := filter + GetFldName(tmpPropList.PropNames)+'='
else
Continue;

case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+' and ';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+' and ';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+' and ';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+' and ';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
filter := filter + QuotedStr('1')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
filter := filter + QuotedStr('0')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = '' then
filter := filter + QuotedStr('0')+' and ';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+' and ';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+' and ';
end;
end;

Result := Copy(tmpSQL+filter,0, length(tmpSQL+filter)-4);
end;

function TDAOAdapter.getMaxCountString(Const pTO: TDataTransferObject): String;
begin
Result := 'select count(*) as mySum from '+pTO.tbName+ ' where 1=1 ';
end;

function TDAOAdapter.getSearchSQLString(Const pTO: TDataTransferObject): String;
var
i,j: Integer;
tmpSQL, tmpFid, tmpTbname: String;
tmpPropList, tmpProp2: TMPropList;
tmpObj: TObject;
tmpInfo: TTypeInfo;
begin
tmpSQL := 'select ';
if not pTO.isDetail then
begin
//单表情况:
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames) +','
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL +' FROM '+tmpTbname+' where 1=1';
Result := tmpSQL;
end
else
begin
//明细表情况:
tmpPropList := pTO.FPropList;
tmpSQL := 'select ';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkClass:
begin
tmpObj := GetObjectProp(pTO, tmpPropList.Props);
tmpProp2 := TDataTransferObject(tmpObj).FPropList;
tmpTbname := TDataTransferObject(tmpObj).tbName;
for j:=0 to tmpProp2.PropCount-1do
begin
if GetFldName(tmpProp2.PropNames[j])<>'' then
tmpSQL := tmpSQL + tmpTbname +'.'+GetFldName(tmpProp2.PropNames[j]) +','
end;
end;
end;

end;

tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL + ' FROM ';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkClass:
begin
tmpObj := GetObjectProp(pTO, tmpPropList.Props);
tmpProp2 := TDataTransferObject(tmpObj).FPropList;
tmpTbname := TDataTransferObject(tmpObj).tbName;
tmpSQL := tmpSQL + tmpTbname+',';
end;
end;
end;

tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL + ' Where '+pTO.IndexInfo;
Result := tmpSQL;
end;

end;

function TDAOAdapter.getInsertSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'insert '+tmpTbname+' (';
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames)+','
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1)+') values(';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+',';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+',';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+',';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+',';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL + QuotedStr('1')+',';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL + QuotedStr('0')+',';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL + QuotedStr('0')+',';
end;

tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+',';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+',';
end;

end;
Result := Copy(tmpSQL,0, length(tmpSQL)-1)+')';
end;

function TDAOAdapter.getUpdateSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
filter: String;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'Update '+tmpTbname+' set ';
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames)+'=';
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+',';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+',';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+',';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+',';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL + QuotedStr('1')+',';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL + QuotedStr('0')+',';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL + QuotedStr('0')+',';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+',';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+',';
end;
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);

//主键产生Update语句
filter := ' Where 1=1 and ';
for i:=0 to tmpPropList.PropCount-1do
begin

if (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true) then
filter := filter + GetFldName(tmpPropList.PropNames)+'='
else
Continue;

case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+' and ';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+' and ';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+' and ';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+' and ';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
filter := filter + QuotedStr('1')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
filter := filter + QuotedStr('0')+' and ';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
filter := filter + QuotedStr('0')+' and ';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+' and ';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+' and ';
end;
end;

Result := Copy(tmpSQL+filter,0, length(tmpSQL+filter)-4);
end;

function TDAOAdapter.getDeleteSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'Delete '+tmpTbname+' where 1=1 ';
for i:=0 to tmpPropList.PropCount-1do
begin
if not( (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true)) then
Continue;
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+IntToStr( GetOrdProp(pTO, tmpPropList.Props) );
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+IntToStr( GetInt64Prop(pTO, tmpPropList.Props) );
tkChar, tkLString, tkString:
if not (Trim( GetStrProp(pTO, tmpPropList.Props) ) = '') and (GetFldName(tmpPropList.PropNames)<>'') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetStrProp(pTO, tmpPropList.Props) );
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetSetProp(pTO, tmpPropList.Props) );
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('1');
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('0');
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('0');
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+FloatToStr( GetFloatProp(pTO, tmpPropList.Props) );
tkWChar, tkWString:
if not (Trim( GetStrProp(pTO, tmpPropList.Props) ) = '') and (GetFldName(tmpPropList.PropNames)<>'') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) );
end;
end;

Result := tmpSQL;
end;

destructor TDAOAdapter.Destroy;
begin
inherited Destroy;
end;

end.
 
为什么就必须使用主从表,就因为数据库帮我们做了一些事情么?
如果麻烦可以自己写逻辑代码控制,好像也不是很麻烦
 
多人接受答案了。
 
楼主怎么解决的?
用这种方法在大数据量的情况下还是有优势的
 
后退
顶部