Procédures stockées sous Access [C++.Net]

Procédures stockées sous Access [C++.Net] - SQL/NoSQL - Programmation

Marsh Posté le 17-10-2005 à 22:03:52    

Salut à tous,
 
j'aimerais savoir comment faire des procédures stockées sous Access et comment y accéder via C++.Net. Je crois qu'Access appelle ça des Requête Eenregistrées, mais j'ai besoin de requêtes pouvant avoir des contraintes. Par exemple, je reçois un paramètre dans ma procédure, et je veux valider le paramètre. En SQL on le fait à l'aide de CONSTRAINT. Donc j'aimerais que tout mon code de vérification se fasse dans ma bd Access. De cette façon, je n'ai qu'à appeler ma procédure SQL à partir de mon programme C++ et je peux lui lancer n'importe quoi en paramètres, car la bd s'occupe de la vérification et renvoie une erreur s'il y a lieu.
 
Est-ce possible de faire cela avec Access (2003 ou 2002)? C'est possible avec Oracle, je le sais, mais raison de portabilité, Access sera plus convivial à mon projet.
 
Merci,
 
Alpha :)

Reply

Marsh Posté le 17-10-2005 à 22:03:52   

Reply

Marsh Posté le 18-10-2005 à 11:34:51    

Salut,
 
Alors, Access gère deux types de vues/procédure stockées
 
Soit c'est une requête enregistrée, soit une macro. Pour les macros, à priori, impossible de les lancer sans créer une instance du logiciel Access depuis ton programme.
 
Pour les requêtes paramètrées, si elle est de type "select", alors c'est facile, l'appelle comme une simple requête.
 
Pour les autres types de requêtes (update, insert, delete), là, j'ai un doute, car je ne l'ai jamais fait.
 
A mon avis, tu fais un bête appel au nom de la requête comme si tu allais lancer une procédure stockées, avec un objet "ADODB.Command".
 
A tester.

Reply

Marsh Posté le 18-10-2005 à 11:49:48    

J'ai créé une table "test" (id, val)
 
J'ai créé une requêtes d'insertion "query1" (INSERT INTO tst ( val ) VALUES ([:val]);)
 
Et dans un programme (en C#, je n'ai pas installé C++), ça donne :
 

Code :
  1. using System;
  2. using System.Drawing;
  3. using System.Collections;
  4. using System.ComponentModel;
  5. using System.Windows.Forms;
  6. using System.Data;
  7. namespace testdb
  8. {
  9. /// <summary>
  10. /// Summary description for Form1.
  11. /// </summary>
  12. public class Form1 : System.Windows.Forms.Form
  13. {
  14.  private System.Data.OleDb.OleDbConnection oleDbConnection1;
  15.  private System.Windows.Forms.Button button1;
  16.  /// <summary>
  17.  /// Required designer variable.
  18.  /// </summary>
  19.  private System.ComponentModel.Container components = null;
  20.  public Form1()
  21.  {
  22.   //
  23.   // Required for Windows Form Designer support
  24.   //
  25.   InitializeComponent();
  26.   //
  27.   // TODO: Add any constructor code after InitializeComponent call
  28.   //
  29.  }
  30.  /// <summary>
  31.  /// Clean up any resources being used.
  32.  /// </summary>
  33.  protected override void Dispose( bool disposing )
  34.  {
  35.   if( disposing )
  36.   {
  37.    if (components != null)
  38.    {
  39.     components.Dispose();
  40.    }
  41.   }
  42.   base.Dispose( disposing );
  43.  }
  44.  #region Windows Form Designer generated code
  45.  /// <summary>
  46.  /// Required method for Designer support - do not modify
  47.  /// the contents of this method with the code editor.
  48.  /// </summary>
  49.  private void InitializeComponent()
  50.  {
  51.   this.oleDbConnection1 = new System.Data.OleDb.OleDbConnection();
  52.   this.button1 = new System.Windows.Forms.Button();
  53.   this.SuspendLayout();
  54.   //  
  55.   // oleDbConnection1
  56.   //  
  57.   this.oleDbConnection1.ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Database Password=;Data Source=""C:\Documents and Settings\Administrateur\Mes documents\test.mdb"";Password=;Jet OLEDB:Engine Type=5;Jet OLEDB:Global Bulk Transactions=1;Provider=""Microsoft.Jet.OLEDB.4.0"";Jet OLEDB:System database=;Jet OLEDB:SFP=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:New Database Password=;Jet OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;User ID=Admin;Jet OLEDB:Encrypt Database=False";
  58.   //  
  59.   // button1
  60.   //  
  61.   this.button1.Location = new System.Drawing.Point(120, 80);
  62.   this.button1.Name = "button1";
  63.   this.button1.Size = new System.Drawing.Size(96, 56);
  64.   this.button1.TabIndex = 0;
  65.   this.button1.Text = "button1";
  66.   this.button1.Click += new System.EventHandler(this.button1_Click);
  67.   //  
  68.   // Form1
  69.   //  
  70.   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
  71.   this.ClientSize = new System.Drawing.Size(292, 273);
  72.   this.Controls.Add(this.button1);
  73.   this.Name = "Form1";
  74.   this.Text = "Form1";
  75.   this.Load += new System.EventHandler(this.Form1_Load);
  76.   this.ResumeLayout(false);
  77.  }
  78.  #endregion
  79.  /// <summary>
  80.  /// The main entry point for the application.
  81.  /// </summary>
  82.  [STAThread]
  83.  static void Main()
  84.  {
  85.   Application.Run(new Form1());
  86.  }
  87.  private void Form1_Load(object sender, System.EventArgs e)
  88.  {
  89.  }
  90.  private void button1_Click(object sender, System.EventArgs e)
  91.  {
  92.   oleDbConnection1.Open();
  93.   System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("Query1", oleDbConnection1);
  94.   cmd.CommandType = System.Data.CommandType.StoredProcedure;
  95.   System.Data.OleDb.OleDbParameter param = cmd.Parameters.Add("val", System.Data.OleDb.OleDbType.VarChar, 50);
  96.   param.Value = "test de val";
  97.   cmd.ExecuteNonQuery();
  98.   oleDbConnection1.Close();
  99.  }
  100. }
  101. }


 
(voir la partir du bouton pour voir l'appel à la requête)

Reply

Marsh Posté le 18-10-2005 à 11:51:06    

Et ça marche :
 
id val
1 test
2 test de val
 
=> La première ligne, je l'ai créée depuis Access pour tester la requête
=> La seconde ligne a bien été créée depuis le programme

Reply

Marsh Posté le 18-10-2005 à 11:52:53    

T'ain, y'a pas à dire, Access  c'est assez limité, mais mine de rien c'est quand même vachement puissant et simple d'emplois :)
 
Et dire que je viens de faire un truc en 10 minutes alors que je ne l'avais jamais fait ! :sol:

Reply

Marsh Posté le 18-10-2005 à 17:24:49    

Wow merci beaucoup Arjuna, j'essaie ça cette apres midi et je t'en reparle ;)
 
Sinon pour les contraintes sous Access vous savez si ça se fait? Vérifier les valeurs reçues dans la requête directement au lieu de les vérifier avant de les envoyer?

Reply

Marsh Posté le 18-10-2005 à 19:18:28    

Donne un exemple de ce que tu veux faire.
 
Pour moi, une contrainte, c'est pas au moment de la requête que c'est fait (du moins, c'est pas dans la requête) mais directement au moment de la modification d'une valeur, au niveau de la table.
 
Access supporte quelques contraintes, genre masque ou calcul, mais j'ai vu ça pendant 15 minutes sous Access 2 il y a 7 ans pendant mes études, alors je peux pas trop t'en dire plus ;)
 
Dans Access, lors de la modification de la table (mode design), t'as deux champs :
 
Expression => A priori, c'est la valeur par défaut, mais ça peut peut-être aussi faire office de règle
Format (ou masque, de tête je sais pas) => Là, tu peux au moins imposé un masque de saisie, mais je ne sais pas si tu peux lui faire faire des traîtements plus complexes. Si tu sais faire dans SQL Server sans passer par l'écran dédié aux contraintes ni par le SQL, alors c'est pareil (dans l'écran de design d'une table dans Entreprise Manager, mais je ne sais pas plus m'en servir de celui-là :D)

Reply

Marsh Posté le 18-10-2005 à 19:24:02    

Pour les contraintes, c'est le Framework qui s'en charge...
 
Enfin ça dépend. Si t'utilises des DataSets et des DataAdapters, ça va râler si tu remplis le DataSet avec des mauvaises données. Pareil lors de la mise à jour via le DataAdapter.

Reply

Marsh Posté le 18-10-2005 à 19:38:43    

Perso, moins le FrameWork en fait, et mieu je me porte :
1) C'est pas lui le SGBD
2) C'est dont pas à lui de garantir la bonne santé des données
3) Même s'il offre un tas de règles, n'étant pas centralisé il reste un gruyère
4) Si un autre soft (ancienne version, ou autre) vient se connecter à la base, il passera à travers de tes règles prises en charge par le Framework.
 
En résumé, pour moi, les checks effectués dans le FrameWork ne doivent servir qu'à réduire le nombre d'erreurs gérées par le SGBD, en aucun cas à réduire la sécurité des données sur ce dernier.
 
Genre, si un champ est obligatoire dans un formulaire HTML, tu va mettres un JavaScript qui va empêcher la validation si le champ est vide.
Ensuite, dans le PHP, tu vas vérifier que le champ est bien rempli.
Et enfin, la base est setupée avec un champ "not null" et "chaîne vide interdite".
Tu peux virer les contraintes dans le même ordre. Mais il ne faut jamais prendre en aval pour argent comptant les traitements effectués en amont, rien ne les garantis (par contre l'inverse doit être vrai).
 
Tu poste une lettre avec AR à la poste : rien ne te garanti que le destinataire va la recevoir.
Tu reçois l'AR, tout te garanti que le destinataire l'a reçue.
 
En informatique, ça marche comme ça : les couches de bas niveau ne doivent en aucun cas faire confiance aux couches proches de la GUI. Par contre la GUI doit pouvoir avoir une confiance aveugle envers les couches de bas niveau.

Reply

Marsh Posté le 18-10-2005 à 19:41:54    

Enfin, quand je dis "Pareil lors de la mise à jour via le DataAdapter.", c'est le SGBD en dessous qui râle ;) Donc la vérif des données viens bien de Access.
 
Après y'a effectivement une vérification supplémentaire faite par le Framework pour ce qui est des Datasets, mais parfois des choses qui rentrent dans le Dataset ne rentre pas dans le SGBD en dessous.

Reply

Marsh Posté le 18-10-2005 à 19:41:54   

Reply

Marsh Posté le 20-10-2005 à 04:12:59    

Merci les gars ;)
 
Les requetes fonctionnent sous access mais pas les contraintes, alors on a décider de les faire dans le code direct.
 
Mille mercis!

Reply

Marsh Posté le 20-10-2005 à 11:52:49    

Comment ça les contraintes ne marchent pas ?
 
Attends que je fasse un test histoire de vérifier un truc.
 
Mais déjà, dis-nous de quelle contrainte tu parles : un exemple concret.

Reply

Marsh Posté le 20-10-2005 à 12:13:53    

En effet, c'est pire que "ça marche pas"...
J'ai créé une règle. Dans Access, tout marche bien, il fait tous les checks nécessaires.
Mais depuis un programme, non seulement il ne fait pas les checks, mais surtout, il plante systématiquement les requêtes !
 
J'ai mis dans "validation rule" de mon champ :
 
like "A*"
 
si mon prog insère "toto", ça plante.
"Atoto" marche.
 
un peu de doc sur cs validation rules :

Citation :


Show All
 
ValidationRule Property
See AlsoApplies ToExampleSpecificsYou can use the ValidationRule property to specify requirements for data entered into a record, field, or control. When data is entered that violates the ValidationRule setting, you can use the ValidationText property to specify the message to be displayed to the user.
 
Note  The ValidationRule and ValidationText properties don't apply to check box, option button, or toggle button controls when they are in an option group. They apply only to the option group itself.
 
Remarks
Enter an expression for the ValidationRule property setting and text for the ValidationText property setting. The maximum length for the ValidationRule property setting is 2048 characters. The maximum length for the ValidationText property setting is 255 characters.
 
For controls, you can set the ValidationRule property to any valid expression. For field and record validation rules, the expression can't contain user-defined functions, domain aggregate or aggregate functions, the Eval function, or CurrentUser method, or references to forms, queries, or tables. In addition, field validation rules can't contain references to other fields. For records, expressions can include references to fields in that table.
 
You can set the ValidationRule and ValidationText properties by using:
 
The Field Properties section of table Design view (for a field validation rule).  
The property sheet for a table by clicking Properties on the View menu in table Design view (for a record validation rule).  
The property sheet for a control on a form.  
A macro or Visual Basic. In Visual Basic, use a string expression to set these properties.  
For table fields and records, you can also set these properties in Visual Basic by using the DAO ValidationRule property.
 
Microsoft Access automatically validates values based on a field's data type; for example, Microsoft Access doesn't allow text in a numeric field. You can set rules that are more specific by using the ValidationRule property.
 
If you set the ValidationRule property but not the ValidationText property, Microsoft Access displays a standard error message when the validation rule is violated. If you set the ValidationText property, the text you enter is displayed as the error message.
 
For example, when a record is added for a new employee, you can enter a ValidationRule property requiring that the value in the employee's StartDate field fall between the company's founding date and the current date. If the date entered isn't in this range, you can display the ValidationText property message: "Start date is incorrect."
 
If you create a control by dragging a field from the field list, the field's validation rule remains in effect, although it isn't displayed in the control's ValidationRule property box in the property sheet. This is because a field's validation rule is inherited by a control bound to that field.
 
Control, field, and record validation rules are applied as follows:
 
Validation rules you set for fields and controls are applied when you edit the data and the focus leaves the field or control.  
Validation rules for records are applied when you move to another record.  
If you create validation rules for both a field and a control bound to the field, both validation rules are applied when you edit data and the focus leaves the control.  
The following table contains expression examples for the ValidationRule and ValidationText properties.
 
ValidationRule property ValidationText property  
<> 0 Entry must be a nonzero value.  
> 1000 Or Is Null Entry must be blank or greater than 1000.  
Like "A????" Entry must be 5 characters and begin with the letter "A".  
>= #1/1/96# And <#1/1/97# Entry must be a date in 1996.  
DLookup("CustomerID", "Customers", "CustomerID = Forms!Customers!CustomerID" ) Is Null Entry must be a unique CustomerID (domain aggregate functions are allowed only for form-level validation).  
 
 
If you create a validation rule for a field, Microsoft Access doesn't normally allow a Null value to be stored in the field. If you want to allow a Null value, add "Is Null" to the validation rule, as in "<> 8 Or Is Null" and make sure the Required property is set to No.
 
You can't set field or record validation rules for tables created outside Microsoft Access (for example, dBASE, Paradox, or SQL Server). For these kinds of tables, you can create validation rules for controls only.
 
Example
The following example creates a validation rule for a field that allows only values over 65 to be entered. If a number less than 65 is entered, a message is displayed. The properties are set by using the SetFieldValidation function.
 
Dim strTblName As String, strFldName As String
Dim strValidRule As String
Dim strValidText As String, intX As Integer
 
strTblName = "Customers"
strFldName = "Age"
strValidRule = ">= 65"
strValidText = "Enter a number greater than or equal to 65."
intX = SetFieldValidation(strTblName, strFldName, _
    strValidRule, strValidText)
 
Function SetFieldValidation(strTblName As String, _
    strFldName As String, strValidRule As String, _
    strValidText As String) As Integer
 
    Dim dbs As Database, tdf As TableDef, fld As Field
 
    Set dbs = CurrentDb
    Set tdf = dbs.TableDefs(strTblName)
    Set fld = tdf.Fields(strFldName)
    fld.ValidationRule = strValidRule
    fld.ValidationText = strValidText
End Function
   
The next example uses the SetTableValidation function to set record-level validation to ensure that the value in the EndDate field comes after the value in the StartDate field.
 
Dim strTblName As String, strValidRule As String
Dim strValidText As String
Dim intX As Integer
 
strTblName = "Employees"
strValidRule = "EndDate > StartDate"
strValidText = "Enter an EndDate that is later than the StartDate."
intX = SetTableValidation(strTblName, strValidRule, strValidText)
 
Function SetTableValidation(strTblName As String, _
    strValidRule As String, strValidText As String) _
    As Integer
 
    Dim dbs As Database, tdf As TableDef
 
    Set dbs = CurrentDb
    Set tdf = dbs.TableDefs(strTblName)
    tdf.ValidationRule = strValidRule
    tdf.ValidationText = strValidText
End Function

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed