在datasnap客户端中执行动态sql

时间:2012-05-10 13:43:47

标签: delphi-xe2 datasnap

是否可以在datasnap服务器和客户端之间共享数据库连接?

我想在客户端执行动态sql并接收结果。

2 个答案:

答案 0 :(得分:4)

我找到了两种在客户端执行动态sql的方法

1)使用DbxConnection(dbExpress)

// Server code
function TServerMethods1.GetConnection: TDbxConnection;
begin
  Result := DBConnection.DBXConnection;
end;


//Client code
dbxConnection := ServerMethods.GetConnection;
command := dbxConnection.CreateCommand;
command.Text := 'SELECT COUNT(1) FROM clients WHERE name LIKE :name';
param := com.CreateParameter;
param.Name := 'name';
param.DataType := TDBXDataTypes.WideStringType;
param.Value.SetString('%name%');
command.Parameters.AddParameter(param);
reader := command.ExecuteQuery;
reader.Next; // to Fetch row
ShowMessage(reader.Value[0].AsString);

2)使用DataSet后代

服务器端组件

ServerMethods类必须是TDSServerModule后代

  • TConnection descendant
  • TQuery后裔
  • TDataSetProvider(将poAllowCommanedText设置为true)

客户端组件

  • TSqlConnection(用于DataSnap连接)
  • TDsProviderConnection(适用于DataSnap服务器方法)
  • TClientDataSet(设置提供者)

执行查询的代码

CDS.Close; // TClientDataSet
CDS.CommandText := 'SELECT COUNT(*) FROM clients WHERE name LIKE :name';
CDS.Params.ParamByName('name').AsString := '%name%';
CDS.Open;
ShowMessage(CDS.Fields[0].AsString);

服务器端代码:

MainMethods.pas

TMainMethods = class(TDSServerModule)
  PgQuery: TPgQuery;
  PgQueryProvider: TDataSetProvider;
  PgConnection: TPgConnection;
end;

MainMethods.dfm

object MainMethods: TMainMethods
  Height = 248
  Width = 440
  object PgConnection: TPgConnection
    Left = 200
    Top = 32
    ...
  end
  object PgQuery: TPgQuery
    Connection: PgConnection
    Left = 32
    Top = 24
  end
  object PgQueryProvider: TDataSetProvider
    DataSet = PgQuery
    Options = [poAllowCommandText, poUseQuoteChar]
    Left = 120
    Top = 24
  end
end

客户端代码:

client.pas

TVerusClient = class(TDataModule)
  dbxVerusConnection: TSQLConnection;
  dbxSqlConnectionProvider: TDSProviderConnection;
  cdsSqlDataSet: TClientDataSet;
end;

client.dfm

object VerusClient: TVerusClient
  Height = 271
  Width = 415
  object dbxVerusConnection: TSQLConnection
    DriverName = 'DataSnap'
    LoginPrompt = False
    ...
  end
  object dbxSqlConnectionProvider: TDSProviderConnection
    ServerClassName = 'TMainMethods'
    SQLConnection = dbxVerusConnection
    Left = 176
    Top = 32
  end
  object cdsSqlDataSet: TClientDataSet
    ProviderName = 'PgQueryProvider'
    RemoteServer = dbxSqlConnectionProvider
    Left = 176
    Top = 104
  end
end

答案 1 :(得分:0)

DataSnap(多层)应用程序的主要目标是安全性。您无法在远程模式下直接(本机)共享对象(连接,资源),但您可以在会话中更改数据集的SQL。但它并不安全。

// Server Code
procedure TMyServerMethod.ChangeSQL(ASQL:string); // insecure
begin
  AdoQuery1.Active:=false;
  AdoQuery1.SQL.Text:=ASQL; // AdoQuery,DbxExpress,UniDAC,AnyDac,...    
  AdoQuery1.Active:=true;
end;

使用generate proxy作为客户端

// Client Code
procedure TForm1.Button1Click(Sender:TObject);
begin
  Proxy.ChangeSQL('select * from custom_table');// but it is insecure
  // loading remote datasets
end;