参数.As在Oracle / SQL下失败 - 在Oracle下的Parameter.Value 2字节字符

问题描述 投票:8回答:2

更改为FireDAC后,我无法使此代码在MSSQL / Oracle上运行:

with DataFormsettings do
begin
  Close;
  if Params.Count=0 then FetchParams;
  Params.ParamByName('TT_EMP_ID').Asinteger := AEmpID;
  Params.ParamByName('TT_FORM').AString := UpperCase(AKey);  
  Open;
  if (RecordCount>0) then
     S := FieldByName('TT_VIEWDATA').Asstring;     
end;   

AKey和S都是字符串。 Open语句给出错误

[FireDAC][Phys][MSSQL]-338 Param type changed from [ftString] to [ftWidestring]
[FireDAC][Phys][Ora]-338 Param type changed from [ftString] to [ftWidestring]

连接到MSSQL或Oracle数据库时;连接到FireBird时没有。 在FetchParams之后,DataFormsettings.params[1].datatype总是一个ftString

如果我更换

Params.ParamByName('TT_FORM').AString := UpperCase(AKey);  

Params.ParamByName('TT_FORM').Value := UpperCase(AKey);

... Open语句中没有错误。虽然我没有真正理解错误,但我认为已经解决了它。毕竟,这应该是所有默认的Delphi String类型...... 但是现在,对于Oracle(而不是FireBird或MSSQL)而言,S分配失败,因为我看到2字节字符被返回。 S包含:

\'#0'S'#0'o'#0'f'#0't'#0'w'#0'a'#0'r'#0'e'#0'\'#0'T'#0'i'#0'm'#0'e'#0'T'#0'e'#0'l'#0'l'#0'...

我可以用例如

S := TEncoding.Unicode.GetString(FieldByName('TT_VIEWDATA').AsBytes);  

对于Oracle,但(当然)在使用其他两种不起作用的数据库类型时:

No mapping for the Unicode character exists in the target multi-byte code page

我在这里错过了什么?具体来说,我想让AsString检索/分配工作。 请注意,设置AsString属性会在FireDAC TFDParam.AsString documentation中将DataType属性设置为ftWideString或ftString remark。看起来好像参数值赋值只是将类型从ftString切换到ftWideString(由原始错误指示)。

DataFormSettings是客户端应用程序中的TClientDataSet,连接到TDataSetProviderTFDQuery所在的服务器应用程序。查询是

select
  TT_FORMSETTINGS_ID,
  TT_EMP_ID,
  TT_FORM,
  TT_VERSION,
  TT_VIEWDATA
from TT_FORMSETTINGS
where TT_EMP_ID=:TT_EMP_ID
and TT_FORM=:TT_FORM

表格创建如下:

火鸟:

CREATE TABLE TT_FORMSETTINGS
(
  TT_FORMSETTINGS_ID    INTEGER DEFAULT 0 NOT NULL,
  TT_EMP_ID     INTEGER,
  TT_FORM       VARCHAR(50),
  TT_VERSION        INTEGER,
  TT_VIEWDATA       BLOB SUB_TYPE TEXT SEGMENT SIZE 80,
  TT_TAG    INTEGER,
  TT_TAGTYPE    INTEGER,
  TT_TAGDATE    TIMESTAMP
);

甲骨文:

CREATE TABLE TT_FORMSETTINGS
(
  TT_FORMSETTINGS_ID    NUMBER(10,0) DEFAULT 0 NOT NULL,
  TT_EMP_ID     NUMBER(10,0),
  TT_FORM       VARCHAR(50),
  TT_VERSION        NUMBER(10,0),
  TT_VIEWDATA       CLOB,
  TT_TAG    NUMBER(10,0),
  TT_TAGTYPE    NUMBER(10,0),
  TT_TAGDATE    DATE
);

MSSQL:

CREATE TABLE TT_FORMSETTINGS
(
  TT_FORMSETTINGS_ID    INTEGER  NOT NULL CONSTRAINT TT_C0_FORMSETTINGS DEFAULT 0,
  TT_EMP_ID     INTEGER NULL,
  TT_FORM       VARCHAR(50) NULL,
  TT_VERSION        INTEGER NULL,
  TT_VIEWDATA       TEXT NULL,
  TT_TAG    INTEGER NULL,
  TT_TAGTYPE    INTEGER NULL,
  TT_TAGDATE    DATETIME NULL
);

我已经检查过TT_VIEWDATA在所有数据库中包含正确的数据;它是一个包含CRLF的长字符串:

\Software\TimeTell\Demo8\Forms\TFormTileMenu'#$D#$A'Version,1,80502'#$D#$A'\Software\TimeTell\Demo8\Forms\TFormTileMenu\TileControlMenu'#$D#$A'\Software\TimeTell\Demo8\Forms\TFormTileMenu\TileControlMenu\FormTileMenu.TileControlMenu'#$D#$A'Version,4,2'#$D#$A'\Software\TimeTell\Demo8\Forms\TFormTileMenu\TileControlMenu\FormTileMenu.TileControlMenu...

笔记:

  • 目前正在测试SQL Server 2008和Oracle 10,但我希望这对其他版本没有什么不同。
  • FWIW,select * from NLS_database_PARAMETERS where parameter like '%CHARACTERSET%'返回NLS_CHARACTERSET=WE8MSWIN1252NLS_NCHAR_CHARACTERSET=AL16UTF16 查询SELECT dump(dbms_lob.substr(tt_viewdata,100,1), 1016), tt_viewdata FROM tt_formsettings确认CLOB包含Win1252代码页的ASCII字节: Typ=1 Len=100 CharacterSet=WE8MSWIN1252: 5c,53,6f,66,74,77,61,72,65,5c,54,69,6d,65,54,65,6c,6c,5c,44,65,...
  • FieldByName().AsANSIString给出与FieldByName().AsString相同的结果

附加信息:这是一个遗留应用程序,在DataFormsettings TClientDataset上具有持久字段定义。 TT_VIEWDATA被定义为TMemoField

DataFormsettingsTT_VIEWDATA: TMemoField;

在一个小的testapp(直接连接到Oracle;而不是客户端 - 服务器)我让Delphi添加字段定义然后它说:

DataFormsettingsTT_VIEWDATA: TWideMemoField;

如果我在主应用程序中使用它,Oracle工作正常,但后来我得到MSSQL的“垃圾”。

我还尝试为Oracle连接设置映射规则,如(许多变体):

with AConnection.FormatOptions.MapRules.Add do
begin
  SourceDataType := dtWideMemo;
  TargetDataType := dtMemo;
end;
AConnection.FormatOptions.OwnMapRules := true;

但这没有帮助。

oracle delphi firedac delphi-10.2-tokyo
2个回答
5
投票

这是它不起作用的原因:

FireDAC.Stan.Option

procedure TFDFormatOptions.ColumnDef2FieldDef()
...
dtWideHMemo:
  // Here was ftOraClob, but then will be created TMemoField,
  // which does not know anything about Unicode. So, I have
  // changed to ftFmtMemo. But probably may be problems ...
  ADestFieldType := ftWideMemo;

的确,可能是问题。

解决方案是添加将dtWideHMemo转换为dtMemo的映射规则。 之后,读取和写入CLOB .AsString工作正常。

在Embarcadero Quality Portal报道为RSP-19600


为了完整性:因为我的其他答案中提到的映射不再有效,您必须使用.Value而不是.AsString.更改对参数的访问权限


1
投票

这不是一个明确的解决方案,请参阅代码块之前的最后一个注释。它仍然像一个黑客。我不是将它添加到问题中(因为'尝试'),因为最终这会起作用。

有两件事情正在发生,他们都可以通过以下更改来解决:

  1. Param类型更改了Params值赋值的错误
  2. 字段定义和FieldByName().AsString检索/分配不起作用

请注意,我在整个应用程序中受设计时字段定义的限制,该应用程序必须处理所有三种数据库类型,特别是DataFormSettingsTT_VIEWDATA持久字段是TMemoField

使用问题底部提到的表定义,如果您设置了TFDConnection -> TFDQuery -> TDataSetProvider -> TClientDataSet并使用Add all fields添加字段定义,则DataFormSettingsTT_VIEWDATA将是以下类型:

  • TMemoFieldBlobType=ftMemoField for FireBird
  • TMemoFieldBlobType=ftWideMemoField for MSSQL
  • TWideMemoFieldBlobType=ftWideMemoField for Oracle。

手动编辑.DFM和.PAS以将Oracle TWideMemoField设置回TMemoField工作(好吧,我不必更改它,它是遗留代码)如果我还:

  • 在运行时强制BlobType=ftWideMemoField设计时间TMemoFields(我可以在我的所有数据模块下降的父级中的OnCreate中执行此操作);
  • 仅作为TEncoding.Unicode.GetString(FieldByName(SFormSettingsViewData).AsBytes)处理Oracle的字符串检索。

但这仍然不是最佳的。我的客户端代码与TClientDataSet will now have to know what kind of database it is。我在客户端应用程序中有手段查询服务器。

以下是包含以下更改的示例应用:

uFireDacOracleBlob.pas文件:

unit uFireDacOracleBlob;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
  FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.Oracle,
  FireDAC.Phys.OracleDef, FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS,
  FireDAC.DApt.Intf, FireDAC.DApt, Datasnap.DBClient, Datasnap.Provider,
  Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.StdCtrls, Vcl.ExtCtrls,
  FireDAC.Phys.MSSQL, FireDAC.Phys.MSSQLDef, FireDAC.Phys.IB,
  FireDAC.Phys.IBDef, FireDAC.Phys.FBDef, FireDAC.Phys.IBBase, FireDAC.Phys.FB,
  FireDAC.Phys.ODBCBase;

type
  TFrmFireDacOracleBlob = class(TForm)
    FDConnection1: TFDConnection;
    FDPhysOracleDriverLink1: TFDPhysOracleDriverLink;
    FDQuery1: TFDQuery;
    DataSetProvider1: TDataSetProvider;
    ClientDataSet1: TClientDataSet;
    Edit0: TEdit;
    Label1: TLabel;
    LblPos0: TLabel;
    RGpDB: TRadioGroup;
    BtnOpen: TButton;
    FDConnection2: TFDConnection;
    FDQuery2: TFDQuery;
    DataSetProvider2: TDataSetProvider;
    ClientDataSet2: TClientDataSet;
    FDConnection0: TFDConnection;
    FDQuery0: TFDQuery;
    DataSetProvider0: TDataSetProvider;
    ClientDataSet0: TClientDataSet;
    FDPhysMSSQLDriverLink1: TFDPhysMSSQLDriverLink;
    FDPhysFBDriverLink1: TFDPhysFBDriverLink;
    ClientDataSet0TT_FORMSETTINGS_ID: TIntegerField;
    ClientDataSet0TT_EMP_ID: TIntegerField;
    ClientDataSet0TT_FORM: TStringField;
    ClientDataSet0TT_VERSION: TIntegerField;
    ClientDataSet0TT_VIEWDATA: TMemoField;

    ClientDataSet1TT_FORMSETTINGS_ID: TIntegerField;
    ClientDataSet1TT_EMP_ID: TIntegerField;
    ClientDataSet1TT_FORM: TStringField;
    ClientDataSet1TT_VERSION: TIntegerField;
    ClientDataSet1TT_VIEWDATA: TMemoField;

    ClientDataSet2TT_FORMSETTINGS_ID: TIntegerField;
    ClientDataSet2TT_EMP_ID: TIntegerField;
    ClientDataSet2TT_FORM: TStringField;
    ClientDataSet2TT_VERSION: TIntegerField;
    ClientDataSet2TT_VIEWDATA: TMemoField;
    BtnSet: TButton;
    Label2: TLabel;
    LblPos1: TLabel;
    Edit1: TEdit;
    Label4: TLabel;
    LblPos2: TLabel;
    Edit2: TEdit;
    BtnParam: TButton;
    procedure BtnOpenClick(Sender: TObject);
    procedure BtnSetClick(Sender: TObject);
    procedure BtnParamClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FStrFirebird,
    FStrOracle,
    FStrMSSQL   :String;
    procedure ShowString(AStr: String; ALbl: TLabel; AEdit: TEdit);
  public
  end;

var
  FrmFireDacOracleBlob: TFrmFireDacOracleBlob;

implementation

{$R *.dfm}

const
   cSQLText = 'select TT_FORMSETTINGS_ID,TT_EMP_ID,TT_FORM,TT_VERSION,TT_VIEWDATA from TT_FORMSETTINGS where TT_EMP_ID=:TT_EMP_ID and TT_FORM=:TT_FORM';

procedure TFrmFireDacOracleBlob.BtnParamClick(Sender: TObject);
begin
  case RGpDB.ItemIndex of
     0: begin
           FDQuery0.SQL.Text := cSQLText;
           with ClientDataSet0 do
           begin
              if Params.Count=0 then FetchParams;
              Params.ParamByName('TT_EMP_ID').Asinteger := 1;
              Params.ParamByName('TT_FORM').AsString := 'TFORMTILEMENU';
              Open;
              if (RecordCount>0) then
                 FStrFirebird := FieldByName('TT_VIEWDATA').Asstring;
              ShowString(FStrFireBird,LblPos0,Edit0);
           end;
        end;
     1: begin
           FDQuery1.SQL.Text := cSQLText;
           with ClientDataSet1 do
           begin
              if Params.Count=0 then FetchParams;
              Params.ParamByName('TT_EMP_ID').Asinteger := 1;
              Params.ParamByName('TT_FORM').AsString := 'TFORMTILEMENU';
              Open;
              if (RecordCount>0) then
                 // FStrOracle := FieldByName('TT_VIEWDATA').Value;
                 FStrOracle := TEncoding.Unicode.GetString(FieldByName('tt_viewdata').AsBytes);
              ShowString(FStrOracle,LblPos1,Edit1);
           end;
        end;
     2: begin
           FDQuery2.SQL.Text := cSQLText;
           with ClientDataSet2 do
           begin
              if Params.Count=0 then FetchParams;
              Params.ParamByName('TT_EMP_ID').Asinteger := 1;
              Params.ParamByName('TT_FORM').AsString := 'TFORMTILEMENU';
              Open;
              if (RecordCount>0) then
                 FStrMSSQL := FieldByName('TT_VIEWDATA').Asstring;
              ShowString(FStrMSSQL,LblPos2,Edit2);
           end;
        end;
  end;
end;

procedure TFrmFireDacOracleBlob.BtnSetClick(Sender: TObject);
begin
  case RGpDB.ItemIndex of
     0: begin
           FStrFirebird := FStrFirebird + #13#10'Added another line';
           ClientDataSet0.Edit;
           ClientDataSet0.FieldByName('tt_viewdata').Value := FStrFireBird;
           ClientDataSet0.ApplyUpdates(0);
        end;
     1: begin
           FStrOracle := FStrOracle + #13#10'Added another line';
           ClientDataSet1.Edit;
           // ClientDataSet1.FieldByName('tt_viewdata').AsString := FStrOracle; // does not work
           // ClientDataSet1.FieldByName('tt_viewdata').Value := FStrOracle;    // does not work
           ClientDataSet1.FieldByName('tt_viewdata').Value := TEncoding.Unicode.GetBytes(FStrOracle);
           // ClientDataSet1.FieldByName('tt_viewdata').AsBytes := TEncoding.Unicode.GetBytes(FStrOracle);  Also works
           ClientDataSet1.ApplyUpdates(0);
        end;
     2: begin
           FStrMSSQL := FStrMSSQL + #13#10'Added another line';
           ClientDataSet2.Edit;
           ClientDataSet2.FieldByName('tt_viewdata').AsString := FStrFireBird;
           ClientDataSet2.ApplyUpdates(0);
        end;
  end;
end;

procedure TFrmFireDacOracleBlob.FormCreate(Sender: TObject);
var i: integer;
begin
   for i := 0 to self.ComponentCount-1 do
      if (self.Components[i] is TMemoField) then
         (self.Components[i] as TMemoField).BlobType := ftWideMemo;
end;

procedure TFrmFireDacOracleBlob.ShowString(AStr: String; ALbl: TLabel; AEdit: TEdit);
begin
  ALbl.Caption := IntToStr(Pos(#13#10,AStr));
  AEdit.Text := AStr;
end;

procedure TFrmFireDacOracleBlob.BtnOpenClick(Sender: TObject);
begin
  case RGpDB.ItemIndex of
     0: begin
           // SetFireBirdMapRules(FDConnection1);   Design time
           ClientDataSet0.Open;
           FStrFirebird := ClientDataSet0.FieldByName('tt_viewdata').AsString;
           ShowString(FStrFireBird,LblPos0,Edit0);
        end;
     1: begin
           // SetOracleMapRules(FDConnection1);   Design time
           ClientDataSet1.Open;
           // FStrOracle := ClientDataSet1.FieldByName('tt_viewdata').AsString;
           FStrOracle := TEncoding.Unicode.GetString(ClientDataSet1.FieldByName('tt_viewdata').AsBytes);
           ShowString(FStrOracle,LblPos1,Edit1);
        end;
     2: begin
           // SetMSSQLMapRules(FDConnection1);   Design time
           ClientDataSet2.Open;
           FStrMSSQL := ClientDataSet2.FieldByName('tt_viewdata').AsString;
           ShowString(FStrMSSQL,LblPos2,Edit2);
        end;
  end;
end;

end.

uFireDacOracleBlob.dfm文件:

object FrmFireDacOracleBlob: TFrmFireDacOracleBlob
  Left = 0
  Top = 0
  Caption = 'FireDac and Oracle Clobs'
  ClientHeight = 278
  ClientWidth = 577
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 32
    Top = 161
    Width = 91
    Height = 13
    Caption = 'Position first CRLF:'
  end
  object LblPos0: TLabel
    Left = 128
    Top = 161
    Width = 6
    Height = 13
    Caption = '0'
  end
  object Label2: TLabel
    Left = 32
    Top = 203
    Width = 91
    Height = 13
    Caption = 'Position first CRLF:'
  end
  object LblPos1: TLabel
    Left = 128
    Top = 203
    Width = 6
    Height = 13
    Caption = '0'
  end
  object Label4: TLabel
    Left = 32
    Top = 245
    Width = 91
    Height = 13
    Caption = 'Position first CRLF:'
  end
  object LblPos2: TLabel
    Left = 128
    Top = 245
    Width = 6
    Height = 13
    Caption = '0'
  end
  object Edit0: TEdit
    Left = 32
    Top = 138
    Width = 505
    Height = 21
    TabOrder = 0
  end
  object RGpDB: TRadioGroup
    Left = 32
    Top = 8
    Width = 249
    Height = 33
    Columns = 3
    ItemIndex = 0
    Items.Strings = (
      'FireBird'
      'Oracle'
      'MSSQL')
    TabOrder = 1
  end
  object BtnOpen: TButton
    Left = 32
    Top = 56
    Width = 75
    Height = 25
    Caption = 'Open Table'
    TabOrder = 2
    OnClick = BtnOpenClick
  end
  object BtnSet: TButton
    Left = 120
    Top = 56
    Width = 75
    Height = 25
    Caption = 'Update field'
    TabOrder = 3
    OnClick = BtnSetClick
  end
  object Edit1: TEdit
    Left = 32
    Top = 180
    Width = 505
    Height = 21
    TabOrder = 4
  end
  object Edit2: TEdit
    Left = 32
    Top = 222
    Width = 505
    Height = 21
    TabOrder = 5
  end
  object BtnParam: TButton
    Left = 32
    Top = 96
    Width = 104
    Height = 25
    Caption = 'Open with params'
    TabOrder = 6
    OnClick = BtnParamClick
  end
  object FDConnection1: TFDConnection
    Params.Strings = (
      'User_Name=testv4'
      'Password=testv4'
      'Database=VS2003-2005-10'
      'DriverID=Ora')
    FormatOptions.AssignedValues = [fvMapRules]
    FormatOptions.OwnMapRules = True
    FormatOptions.MapRules = <
      item
        SourceDataType = dtBCD
        TargetDataType = dtInt32
      end
      item
        SourceDataType = dtFmtBCD
        TargetDataType = dtDouble
      end>
    Connected = True
    LoginPrompt = False
    Left = 312
    Top = 72
  end
  object FDPhysOracleDriverLink1: TFDPhysOracleDriverLink
    Left = 368
    Top = 72
  end
  object FDQuery1: TFDQuery
    Connection = FDConnection1
    SQL.Strings = (
      'select * from tt_formsettings')
    Left = 416
    Top = 72
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = FDQuery1
    Left = 464
    Top = 72
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 512
    Top = 72
    object ClientDataSet1TT_FORMSETTINGS_ID: TIntegerField
      FieldName = 'TT_FORMSETTINGS_ID'
      Required = True
    end
    object ClientDataSet1TT_EMP_ID: TIntegerField
      FieldName = 'TT_EMP_ID'
    end
    object ClientDataSet1TT_FORM: TStringField
      FieldName = 'TT_FORM'
      Size = 50
    end
    object ClientDataSet1TT_VERSION: TIntegerField
      FieldName = 'TT_VERSION'
    end
    object ClientDataSet1TT_VIEWDATA: TMemoField
      FieldName = 'TT_VIEWDATA'
      BlobType = ftWideMemo
    end
  end
  object FDConnection2: TFDConnection
    Params.Strings = (
      'Database=test'
      'Password=test'
      'User_Name=test'
      'Server=VS2003-2008'
      'DriverID=MSSQL')
    FormatOptions.AssignedValues = [fvMapRules]
    FormatOptions.OwnMapRules = True
    FormatOptions.MapRules = <
      item
        SourceDataType = dtDateTimeStamp
        TargetDataType = dtDateTime
      end>
    Connected = True
    LoginPrompt = False
    Left = 312
    Top = 144
  end
  object FDQuery2: TFDQuery
    Connection = FDConnection2
    SQL.Strings = (
      'select * from tt_formsettings')
    Left = 416
    Top = 144
  end
  object DataSetProvider2: TDataSetProvider
    DataSet = FDQuery2
    Left = 464
    Top = 144
  end
  object ClientDataSet2: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider2'
    Left = 512
    Top = 144
    object ClientDataSet2TT_FORMSETTINGS_ID: TIntegerField
      FieldName = 'TT_FORMSETTINGS_ID'
      Required = True
    end
    object ClientDataSet2TT_EMP_ID: TIntegerField
      FieldName = 'TT_EMP_ID'
    end
    object ClientDataSet2TT_FORM: TStringField
      FieldName = 'TT_FORM'
      Size = 50
    end
    object ClientDataSet2TT_VERSION: TIntegerField
      FieldName = 'TT_VERSION'
    end
    object ClientDataSet2TT_VIEWDATA: TMemoField
      FieldName = 'TT_VIEWDATA'
      BlobType = ftMemo
    end
  end
  object FDConnection0: TFDConnection
    Params.Strings = (
      'Database=D:\Testing\Diverse\FireDacOracleBlob\TIMETELL_DEMO.GDB'
      'User_Name=SYSDBA'
      'Password=masterkey'
      'DriverID=IB')
    FormatOptions.AssignedValues = [fvMapRules]
    FormatOptions.OwnMapRules = True
    FormatOptions.MapRules = <
      item
        SourceDataType = dtDateTimeStamp
        TargetDataType = dtDateTime
      end
      item
        SourceDataType = dtSingle
        TargetDataType = dtDouble
      end>
    Connected = True
    LoginPrompt = False
    Left = 312
    Top = 8
  end
  object FDQuery0: TFDQuery
    Connection = FDConnection0
    SQL.Strings = (
      'select * from tt_formsettings')
    Left = 416
    Top = 8
  end
  object DataSetProvider0: TDataSetProvider
    DataSet = FDQuery0
    Left = 464
    Top = 8
  end
  object ClientDataSet0: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider0'
    Left = 512
    Top = 8
    object ClientDataSet0TT_FORMSETTINGS_ID: TIntegerField
      FieldName = 'TT_FORMSETTINGS_ID'
      Required = True
    end
    object ClientDataSet0TT_EMP_ID: TIntegerField
      FieldName = 'TT_EMP_ID'
    end
    object ClientDataSet0TT_FORM: TStringField
      FieldName = 'TT_FORM'
      Size = 50
    end
    object ClientDataSet0TT_VERSION: TIntegerField
      FieldName = 'TT_VERSION'
    end
    object ClientDataSet0TT_VIEWDATA: TMemoField
      FieldName = 'TT_VIEWDATA'
      BlobType = ftMemo
    end
  end
  object FDPhysMSSQLDriverLink1: TFDPhysMSSQLDriverLink
    Left = 368
    Top = 144
  end
  object FDPhysFBDriverLink1: TFDPhysFBDriverLink
    Left = 368
    Top = 8
  end
end

注意:现在(也)参数赋值的工作原理在Data Type Mapping (FireDAC)文档中:

在结果集列的情况下,每个规则定义由驱动程序返回的源数据类型到应用程序首选的目标数据类型的转换。在命令参数的情况下,该规则定义由应用程序指定的目标数据类型到由驱动程序支持的源数据类型的转换。所有规则(不包括基于名称的规则)都适用于两种情况。

© www.soinside.com 2019 - 2024. All rights reserved.