上传客户端的CLIENTDATASET.delta到服务器的clientdataset.data,服务端解析clientdataset的数据生成相应的SQL语句。

相对于直接调用datasetprovider.applyupdates()方法提交数据而言,前者的可控性更强,对于某些要求灵活性很强的场合,前者可能是必须的提交方式。

procedure TBaseService.ApplyUpdates(const Delta: OleVariant; TableName, KeyField: WideString);
var
  Flag: Boolean;
begin
  if VarIsNull(Delta) then exit;
  with (FParent as TDataServer2) do
    begin
      cdsDelta.Close;
      cdsDelta.Data := Delta;
      Flag := cdsDelta.FindField('SYS_STATUS') <> nil;
    end; // with
  if Flag then
    InnerApplyUpdates2(TableName, KeyField)
  else
    InnerApplyUpdates(TableName, KeyField);
end;

function vartosql(value: Variant): wideString;
      var
      tmp:widestring;
      begin
         if (varisnull(Value)) or (varisempty(Value)) then
          Result:='NULL'
         else
          case Vartype(value) of
            varDate:
            begin
              tmp := formatDatetime('yyyy-mm-dd hh:mm:ss', VartoDatetime(Value));
              Result:=Quotedstr(tmp);
            end;
            varString,varOlestr:
              Result:=Quotedstr(Trim(Vartostr(Value)));
            varboolean:
            begin
              if Value then
                Result:='1'
              else
                Result:='0';
            end;
            varSmallint,varInteger,varDouble,varShortInt,varInt64,varLongWord,varCurrency:
            begin
              Result:=trim(Vartostr(Value));
            end;
          else
              Result:=Quotedstr(Trim(Vartostr(Value)));
          end;
      end;

procedure TBaseService.InnerApplyUpdates(TableName, KeyField: WideString);
var
  i: integer;
  s1, s2: string;
  CmdStr: string;
  FieldList: TStringList;
begin
  with (FParent as TDataServer2) do
    begin
      FieldList := TStringList.Create;
      Connection.GetFieldNames(TableName, FieldList);
      if not cdsDelta.Active then cdsDelta.Open;
      for i := 1 to FieldList.Count do
        if cdsDelta.FindField(FieldList[i - 1]) <> nil then
          cdsDelta.FindField(FieldList[i - 1]).Tag := 1;
      FieldList.Free;
      if cdsDelta.RecordCount > 0 then
        begin
          cdsDelta.First;
          s1 := '';
          s2 := '';
          while not cdsDelta.Eof do
            begin
              CmdStr := '';
              case cdsDelta.UpdateStatus of
                usUnmodified:
                  begin
                    s2 := VarToSql(cdsDelta[KeyField]);
                  end;
                usModified:
                  begin
                    s1 := '';
                    for i := 1 to cdsDelta.FieldCount do
                     // if (not cdsDelta.Fields[i - 1].IsNull) and (cdsDelta.Fields[i - 1].Tag = 1) then

if (cdsDelta.Fields[i-1].NewValue <> System.Variants.Unassigned and (cdsDelta.Fields[i - 1].Tag = 1) then
                        begin
                          if s1 = '' then
                            s1 := Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value)
                          else
                            s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value);
                        end;
                    if s1 <> '' then
                      begin
                        CmdStr := 'Update ' + TableName + ' Set ' + s1 + ' Where ' + KeyField + ' = ' + s2;
                      end;
                  end;
                usInserted:
                  begin
                    s1 := '';
                    s2 := '';
                    for i := 1 to cdsDelta.FieldCount do
                      if (not cdsDelta.Fields[i - 1].IsNull) and (cdsDelta.Fields[i - 1].Tag = 1) then
                        begin
                          if s1 = '' then
                            begin
                              s1 := Trim(cdsDelta.Fields[i - 1].FieldName);
                              s2 := VarToSql(cdsDelta.Fields[i - 1].Value);
                            end
                          else
                            begin
                              s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName);
                              s2 := s2 + ',' + VarToSql(cdsDelta.Fields[i - 1].Value);
                            end;
                        end;
                    if s1 <> '' then
                      begin
                        CmdStr := 'Insert into ' + TableName + '(' + s1 + ') Values (' + s2 + ')';
                      end;
                  end;
                usDeleted:
                  begin
                    s2 := VarToSql(cdsDelta[KeyField]);
                    CmdStr := 'Delete ' + TableName + ' Where ' + KeyField + ' = ' + s2;
                  end;
              end;
              if CmdStr <> '' then Cmd.Execute(CmdStr);
              cdsDelta.Next;
            end;
          cdsDelta.First;
          cdsDelta.EmptyDataSet;
          cdsDelta.Close;
        end;
    end;
end;

根据DELTA自动生成SQL语句的更多相关文章

  1. 利用反射自动生成SQL语句(仿Linq)

    转:http://www.cnblogs.com/the7stroke/archive/2012/04/22/2465597.html using System; using System.Colle ...

  2. 使用Excel自动生成sql语句

    在近一段日子里,进入了新的项目组,由于项目需要,经常要将一些Excel表中的数据导入数据库中,以前并没有过多的接触过数据导入与数据处理,对于我来说比较痛苦,今天下午花了几个小时处理数据,但是同事给我提 ...

  3. springboot+mybatis+mysql 利用mybatis自动生成sql语句

    工具和环境 idea,mysql,JDK1.8 效果图如下 结构图如下 java resources sql文件 /* Navicat MySQL Data Transfer Source Serve ...

  4. 城市联动 - 自动生成SQL语句

    字段比较简单/  如果有需要可以自己定制字段和排序/ 一共二级城市联动, 本人业务需要, 所以就两层, 网上关于三层的挺多, 有需要可以借鉴/ 废话不多说, 先看效果图, 代码在下面 <?php ...

  5. Excel 提供数据 更新或者插入数据 通过函数 自动生成SQL语句

    excel 更新数据 ="UPDATE dbo.yt_vehicleExtensionBase SET yt_purchase_date='"&B2&"' ...

  6. 打开powerDesigner时,创建table对应的自动生成sql语句没有注释

    在创建pdm时由于需要在name列填写的是以后要在表中创建的注释信息,comment中则写的说明信息字数比较多.默认情况下在生成建表sql时不能将name生成注释信息,进行如下设置可以讲name生成注 ...

  7. 使用Java注解开发自动生成SQL

    使用注解开发的好处就是减少配置文件的使用.在实际过程中,随着项目越来越复杂,功能越来越多,会产生非常多的配置文件.但是,当配置文件过多,实际维护过程中产生的问题就不容易定位,这样就会徒劳的增加工作量. ...

  8. Excel表格生成sql语句

    假如excel表格中有A.B.C三列数据,希望导入到数据库users表中,对应的字段分别是name,sex,age ,在你的excel表格中增加一列,利用excel的公式自动生成sql语句,方法如下: ...

  9. excel生成sql语句

    很多时候,我们想把excel中数据导入到数据库中. 方法有很多种,比如直接拷贝然后黏贴进编辑状态的框中,这种情况有个弊端,就是excel中每列的数据必须和数据库中一一对应,这个很难,基本上不太可能,数 ...

随机推荐

  1. ui自动化测试 SeleniumBase

    ui自动化 SeleniumBase SeleniumBase是一个自动化web测试框架,它的设计pyse相似,基于selenium和unittest封装的框架,api多,支持命令行多参数执行 文档地 ...

  2. c++ vector容器基本用法

    基本用法 #include<iostream> #include<string> #include<vector> using namespace std; cla ...

  3. for,foreach,$.each()跳出循环的比较

    说起跳出循环,第一时间想起的是 break \ continue,这是经典的for循环. 1.for 循环 先上例子,思考输出结果,体会 break 与 continue 的不同. 1 var arr ...

  4. java只能的round,ceil,floor方法的使用

    三者均位于java.lange包下的Math类中 round: 在原来数字的基础上加上0.5后向下取整, 例如: Math.floor(11.5)=12; Math.floor(-11.5)=-11( ...

  5. jquery 使用off移除事件 使用one绑定一次事件,on绑定事件后触发多次相同的事件的异常

    <!-- jquery 移除事件,绑定一次事件,搜狗 one --> <!DOCTYPE html> <html lang="en"> < ...

  6. js 实现多文件批量下载

    关于兼容性问题: <a href="xxx.docx" target='_blank'></a> 下载文件时,这种写法是没有兼容性问题:但是下载图片时,IE ...

  7. MySQL高级 之 explain执行计划详解(转)

    使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...

  8. 为什么final类型map和list内容可以修改

    URL地址:https://blog.csdn.net/AlbertFly/article/details/76855367

  9. CF280C Game on Tree 概率与期望

    利用期望的线性性,即 $E(a+b)=E(a)+E(b)$. 对于所有点分别求一下期望然后累加即可. code: #include <bits/stdc++.h> #define N 10 ...

  10. 利用QSystemSemaphore和QSharedMemory实现进程间通讯

    https://blog.csdn.net/liji_digital/article/details/70547082 线程间的通讯可以由QSemaphore调控,以保证各个线程对同一资源的访问不冲突 ...