簡體   English   中英

無法使用DataSnap客戶端進行插入

[英]Unable to do an insert using datasnap client

我正在嘗試使用datasnap(以前從未使用過),並且遇到了一個奇怪的問題。 也許我做錯了,我不知道。 我已經在窗體上放置了一個Clientdataset3。 將其鏈接到SQLConnection1(以相同的形式),該SQLConnection1連接到datasnap服務器。 我還已將Clientdataset3鏈接到服務器端的數據集提供程序(允許命令文本),該服務器已鏈接到要插入的表。 但是當我運行時:

procedure TForm3.AdvGlowButton1Click(Sender: TObject);
begin
clientdataset3.CommandText:='insert into "MY_TABLE" (twit) values (:A)';
clientdataset3.Params.ParamByName('A').AsString := cxmemo1.Lines.Text;
clientdataset3.Execute;
end;

我收到“遠程錯誤:沒有這樣的表:插入”

我究竟做錯了什么 ? 使用XE6,數據庫是通過DBX的SQLite。

如果要使用SELECT語句填充CDS,則無需執行發送定制INSERT語句的工作。

你應該可以打電話

ClientDataSet3.Insert;
// populate fields here
ClientDataSet3.Post;

隨后調用ClientDataSet3.ApplyUpdates。

同樣,您可以僅通過調用ClientDataSet3.Delete來執行DELETE。

必要的INSERT,DELETE和UPDATE語句的構造由CDS的提供程序處理。 但是,我無意建議您不能以嘗試的方式進行INSERT-應該可以正常工作。

我無法從這里告訴您INSERT出了什么問題,因此,這里有一些對我有用的代碼(包括CREATE TABLE等語句),因此您可以“發現差異”。 我在日期為2014年6月4日的Win7 64位和v.3.8.5.0的sqlite3.dll上使用XE6。

范例程式碼提供3種插入方式(所有方式都可檢查和運作),兩種使用自訂INSERT陳述式,第三種使用CDS的預設插入行為,可以在程式碼(CDS1.Insert)中按一下,然后按一下[ DBNavigator上的+'按鈕。 默認的CDS插入行為需要特殊處理:盡管服務器上的ID列定義為Autoinc,但是在執行CDS插入時獲取autoinc值是有問題的,因此代碼使用此處描述的方法:

http://edn.embarcadero.com/article/20847

生成一個臨時的負ID值,該值將在CDS ApplyUpdates過程中被替換。 從DFM請注意,由於服務器上的ID列值是64位Integer,因此有必要在鏈接的勘誤部分中提及的關於SqlQuery ID字段中ProviderFlags的措施。

type
  TDataOperation = (doCreateTable, doDropTable, doInsert, doInsertUsingParams, doSelect);

TForm3 = class(TForm)
[...]
{ private declarations }
  ID : Int64;
  function NextID : Int64;
[...]
end;

implementation

{$R *.dfm}

const
  scCreateTable = 'CREATE TABLE [MATable2] ([ID] INTEGER NOT NULL '
    + #13#10 + 'PRIMARY KEY AUTOINCREMENT,  [AName] VARCHAR(20), '
    + #13#10 + '  [AMemo] MEMO)';

  scDropTable =
    'DROP TABLE [MATable2]';

  scInsert1 =
    'INSERT INTO [MATable2] (AName, AMemo) VALUES(''a'', ''A memo'')';

  scSelect =
    'SELECT * FROM [MATable2]';

  scInsertUsingParams =
    'INSERT INTO [MATable2] (AName, AMemo) VALUES(:AName, :AMemo)';

procedure TForm3.PerformTableOperation(Operation : TDataOperation);
var
  Param : TParam;
begin
  if {(Operation in [toCreate, toDrop]) and} CDS1.Active then
    CDS1.Close;
  case Operation of
    doCreateTable : begin
      CDS1.CommandText := scCreateTable;
      CDS1.Execute;
      PerformTableOperation(doSelect);
    end;
    doDropTable : begin
      CDS1.CommandText := scDropTable;
      CDS1.Execute;
    end;
    doSelect : begin
      CDS1.CommandText := scSelect;
      CDS1.Open;
    end;
    doInsert : begin
      CDS1.CommandText := scInsert1;
      CDS1.Execute;
      PerformTableOperation(doSelect);
    end;
    doInsertUsingParams : begin

      CDS1.CommandText := scInsertUsingParams;
//      CDS1.FetchParams;
      CDS1.Params.ParamByName('AName').AsString:= 'bcdef';
      CDS1.Params.ParamByName('AMemo').AsString := 'memo b';
      CDS1.Execute;
      CDS1.Params.Clear;

      PerformTableOperation(doSelect);
    end;
  end;
  if CDS1.Active then  // it won't be  after a toDrop
    CDS1.ApplyUpdates(-1);
end;


procedure TForm3.OpenConnection;
begin
 SqlConnection1.Open;
end;

procedure TForm3.btnCreateClick(Sender: TObject);
begin
  PerformTableOperation(doCreateTable);
end;

[etc ...]

procedure TForm3.btnReopenClick(Sender: TObject);
begin
  CDS1.Close;
  PerformTableOperation(doSelect);
end;

procedure TForm3.btnSelectClick(Sender: TObject);
begin
  PerformTableOperation(doSelect);
end;

procedure TForm3.CDS1AfterDelete(DataSet: TDataSet);
begin
  CDS1.ApplyUpdates(-1);
end;

procedure TForm3.CDS1AfterPost(DataSet: TDataSet);
begin
  CDS1.ApplyUpdates(-1);
end;

procedure TForm3.CDS1NewRecord(DataSet: TDataSet);
begin
  CDS1.FieldByName('ID').AsInteger := NextID;
end;

function TForm3.NextID: Int64;
begin
  Dec(ID);
  Result := ID;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  OpenConnection;
end;

end.

這是部分DFM,可最大程度地減少猜測數據庫組件設置方式的需要。

object Form3: TForm3
[...]
  object DBGrid1: TDBGrid
    Left = 8
    Top = 8
    Width = 456
    Height = 193
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'Tahoma'
    TitleFont.Style = []
    Columns = <
      item
        Expanded = False
        FieldName = 'ID'
        Visible = True
      end
      item
        Expanded = False
        FieldName = 'AName'
        Visible = True
      end
      item
        Expanded = False
        FieldName = 'AMemo'
        Visible = True
      end>
  end
  [...]
  object DBNavigator1: TDBNavigator
    Left = 16
    Top = 216
    Width = 240
    Height = 25
    DataSource = DataSource1
    TabOrder = 6
  end
  object DBMemo1: TDBMemo
    Left = 207
    Top = 259
    Width = 185
    Height = 74
    DataField = 'AMemo'
    DataSource = DataSource1
    TabOrder = 7
  end
  object DBEdit1: TDBEdit
    Left = 24
    Top = 264
    Width = 121
    Height = 21
    DataField = 'AName'
    DataSource = DataSource1
    TabOrder = 8
  end
  object SQLConnection1: TSQLConnection
    ConnectionName = 'SQLITECONNECTION'
    DriverName = 'Sqlite'
    LoginPrompt = False
    Params.Strings = (
      'DriverName=Sqlite'
      'Database=D:\delphi\xe6\sqlite\matestdb.sqlite')
    Connected = True
    Left = 40
    Top = 16
  end
  object SQLQuery1: TSQLQuery
    MaxBlobSize = 1
    Params = <>
    SQL.Strings = (
      'select * from [matable2]')
    SQLConnection = SQLConnection1
    Left = 128
    Top = 16
    object SQLQuery1ID: TLargeintField
      FieldName = 'ID'
      ProviderFlags = [pfInWhere, pfInKey]
    end
    object SQLQuery1AName: TWideStringField
      FieldName = 'AName'
    end
    object SQLQuery1AMemo: TWideMemoField
      FieldName = 'AMemo'
      BlobType = ftWideMemo
      Size = 1
    end
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = SQLQuery1
    Options = [poAllowCommandText, poUseQuoteChar]
    UpdateMode = upWhereKeyOnly
    Left = 216
    Top = 16
  end
  object CDS1: TClientDataSet
    Aggregates = <>
    CommandText = 'select * from MATable2'
    Params = <>
    ProviderName = 'DataSetProvider1'
    BeforeInsert = CDS1BeforeInsert
    AfterInsert = CDS1AfterInsert
    BeforePost = CDS1BeforePost
    AfterPost = CDS1AfterPost
    AfterDelete = CDS1AfterDelete
    OnNewRecord = CDS1NewRecord
    AfterApplyUpdates = CDS1AfterApplyUpdates
    Left = 288
    Top = 16
    object CDS1ID: TLargeintField
      FieldName = 'ID'
    end
    object CDS1AName: TWideStringField
      FieldName = 'AName'
    end
    object CDS1AMemo: TWideMemoField
      FieldName = 'AMemo'
      BlobType = ftWideMemo
      Size = 1
    end
  end
  object DataSource1: TDataSource
    DataSet = CDS1
    Left = 344
    Top = 16
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM