2009-03-17 7 views
3

Je teste actuellement avec:Delphi ClientDataSet en lecture seule

  1. Un SQLConnection qui est dirigée vers une base de données IB.
  2. Un jeu de données SQL dont le champ SQLConnection est défini sur celui défini ci-dessus.
  3. DatasetProvider dont le champ SQLDataset figure dans (2) en tant que valeur de champ Dataset.
  4. ClientDataset, avec le champ ProviderName pointant vers le fournisseur dans (3).

J'utilise la méthode suivante (empruntée à Alister Christie) pour obtenir les données ...

function TForm1.GetCurrEmployee(const IEmployeeID: integer): OleVariant; 
const 
    SQLSELEMP = 'SELECT E.* FROM EMPLOYEE E WHERE E.EMPLOYEEID = %s'; 
begin 
    MainDM.SQLDataset1.CommandText := Format(SQLSELEMP, [Edit1.Text]); 
    Result := MainDM.DataSetProvider1.Data; 
end; 

Ce qui renseigne le DBGrid avec un seul enregistrement. Cependant, quand je modifier manuellement l'enregistrement, cliquez sur Post, puis essayez de valider les modifications, en utilisant

MainDM.ClientDataset1.ApplyUpdates(0); // <<<<<< 

Il bombes, avec le message « SQLDataSet1: Impossible de modifier un ensemble de données en lecture seule. »

J'ai vérifié la propriété ReadOnly du fournisseur et de ClientDataset, et le SQL n'a pas de jointures.

Quelle pourrait être l'origine de l'erreur?

+0

Comment ouvrir le ClientDataSet? La méthode GetCurrEmployee utilise uniquement le SQLDataSet. – mjn

+0

En réponse à mjustin, lorsque la propriété Data d'un DataSetProvider est assignée à ClientDataSet, le ClientDataSet sera actif (il aura des métadonnées en plus des données contenues dans la propriété Data). Un ClientDataSet actif est ouvert. –

Répondre

0

Vérifiez la propriété LiveMode du TIBDataSet.

4

Il semble que votre propriété ClientDataSet.Data est remplie à partir de la propriété Data du DataSetProvider. Avec l'installation que vous avez décrite, vous devriez pouvoir appeler simplement ClientDataSet.Open, qui recevra les données de DataSetProvider. Par défaut, le comportement par défaut de DataSetProvider lorsque vous appelez la méthode ClientDataSet.ApplyUpdates consiste à envoyer une requête SQL à l'objet de connexion, et non le DataSet à partir duquel les données ont été obtenues (en supposant une requête homogène). Assurez-vous que votre propriété DataSetProvider.ResolveToDataSet n'est pas définie sur true. Enfin, sur une note non liée, votre code ci-dessus semble être ouvert à une attaque par injection SQL (même si je n'ai pas testé cela). Il est plus sûr d'utiliser un paramètre pour définir la clause WHERE. Si quelqu'un introduit ce qui suit dans Edit1, vous risquez de rencontrer des problèmes (en supposant qu'InterBase utilise la syntaxe drop table): 1; drop table employee;

+0

+1 pour une bonne réponse, et si heureux de vous voir ici. Ce sera fantastique de vous avoir contribué à SO! – Argalatyr

Questions connexes