1

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

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

4

2 回答 2

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 后代
  • TQuery 后代
  • TDataSetProvider(将 poAllowCommandText 设置为 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);

服务器端代码:

主要方法.pas

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

主要方法.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

客户端代码:

客户端.pas

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

客户端.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
于 2012-05-21T13:08:12.110 回答
0

DataSnap(多层)应用程序的主要目标是安全性。您不能在远程模式下直接(本机)共享对象(连接、资源),但您可以在 Session 上更改数据集的 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;

为客户端使用生成代理

// Client Code
procedure TForm1.Button1Click(Sender:TObject);
begin
  Proxy.ChangeSQL('select * from custom_table');// but it is insecure
  // loading remote datasets
end;
于 2012-05-19T04:32:22.160 回答