IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Enlever la contrainte "Required" d'un champ dans MS Access


Sujet :

C++Builder

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre chevronn�

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par d�faut Enlever la contrainte "Required" d'un champ dans MS Access
    Bonjour � tous,

    J'ai un champ num�rique dans une table Access et j'aimerai lui enlever la contrainte "Required" depuis C++ Builder. J'ai cherch� des solutions sur internet mais sans succ�s: les trois m�thodes que j'ai trouv�es �chouent toutes:

    1) Avec une requ�te SQL "ALTER TABLE table ALTER COLUMN column type NULL" je n'ai pas d'erreur mais l'�tat du champ ne change pas

    2) Avec l'attribut "Attributes" de la colonne en ADOX, l� aussi pas d'erreur mais aucun changement

    3) Avec la propri�t� "Nullable" de la colonne en ADOX, j'ai une erreur lorsque j'essaye d'�crire dans sa propri�t� "Value" (exception "")

    Est-ce que quelqu'un trouverait l'erreur ou aurait une autre m�thode?

    Voici le code avec les trois m�thodes (j'ai remplac� mon objet interne par un TADOConnection pour le rendre plus lisible):
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    //---------------------------------------------------------------------------
    //! Create the SQL command to set/remove constraint on a field to be required
    AnsiString CDBUpdateInterpreterAccess::RequiredFieldSQL(TADOConnection* database,
                                                         const AnsiString& tableName,
                                                         const SFieldDefinition& field) {
     
      //creates an OLE object using the class name
      Variant adox = Variant::CreateObject("ADOX.Catalog");
     
      //Open connection
      adox.OlePropertySet("ActiveConnection",database);
     
      //Get tables collection
      Variant vTables    = adox.OlePropertyGet("Tables");
      Variant table      = vTables.OlePropertyGet("Item",tableName.c_str());
      Variant vColumns   = table.OlePropertyGet("Columns");
      Variant column     = vColumns.OlePropertyGet("Item",field.name.c_str());
     
      // Get the "Required" state to assign to the field
      bool newRequired=false;
     
      // METHOD 1: via "Jet OLEDB:Allow Zero Length" AND "ALTER TABLE"
      // http://stackoverflow.com/questions/3409561/change-columns-properties-values
      {
        Variant property   = column.OlePropertyGet("Properties")
                                   .OlePropertyGet("Item","Jet OLEDB:Allow Zero Length");
        bool allowZero     =(bool)property.OlePropertyGet("Value");
        if (allowZero==newRequired) {   // "allowZero" is inverse of "Required"
          // Apply new value
          property.OlePropertySet("Value",!newRequired);
          // Also change the "NULL" / "NOT NULL" property of the field in ADO
          AnsiString sql=" ALTER TABLE "+tableName
                     +" ALTER COLUMN "+field.name
                     +" "+GetFieldType(field)
                     +" "+(newRequired?"NOT NULL":"NULL");
         TADOQuery* qry=new TADOQuery();
         qry->Connection=database;
         qry->SQL=sql;
         qry->ExecSQL();
         delete qry; qry=NULL;
        }
     
      }
     
     
      // METHOD 2: via the "Attributes" of the column
      // http://msdn.microsoft.com/en-us/library/ms681024%28v=VS.85%29.aspx
      //
      {
        int  attributes    = (int)column.OlePropertyGet("Attributes");
        bool oldRequired   = !(attributes&2);  //adColNullable=2 (inverse of NOT NULL)
        // Compare it to the new state to set
        if (oldRequired!=newRequired) {
          // Different: set the new state
          int newValue=(newRequired?attributes^2:attributes|2); //adColNullable=2 (inverse of "Required")
          column.OlePropertySet("Attributes",newValue);
        }
        // Test if change was applied
        attributes    = (int)column.OlePropertyGet("Attributes");
      }
     
     
      // METHOD 3: via the "Nullable" property of the column
      // http://msdn.microsoft.com/en-us/library/ms676554%28v=VS.85%29.aspx
      // http://www.pcreview.co.uk/forums/re-change-field-required-property-adox-t1685138.html
      {
        Variant property   = column.OlePropertyGet("Properties")
                                   .OlePropertyGet("Item","Nullable");
        bool nullable      =(bool)property.OlePropertyGet("Value");
        if (nullable==newRequired)) {    // "nullable" is inverse of "Required"
          try {
            property.OlePropertySet("Value",!newRequired); // Also tried to replace true by "True"
          } catch (...) {
            int error=1;
          }
        }
        // Test if change was applied
        nullable   =(bool)property.OlePropertyGet("Value");
      }
     
     
      // Close connection
      adox = Unassigned;
     
      //Refresh connection
      RefreshConnection(database);
     
      // No additionnal command to execute
      return AnsiString();
     
    }

  2. #2
    R�dacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par d�faut
    Salut Patrick Seuret
    Si c'est une table Access, dans la FAQ Access il est dit que l'on peut verrouiller les modifications (ajout suppression modification), c'est peut etre une piste, si Fbartolo passe il aura peut etre une solution

  3. #3
    Membre chevronn�

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par d�faut
    Bonjour Blondelle,

    Merci pour ta proposition, mais je n'ai pas l'impression que c'est �a car ma base n'est pas prot�g�e (j'arrive � changer le flag manuellement depuis Access et aussi � renommer des colonnes avec ADOX comme dans mon code).

    Sinon, pour information, concernant la m�thode 1, j'ai essay� d'ex�cuter la commande suivant depuis Access:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    currentdb.Execute "ALTER TABLE myTable ALTER COLUMN myColumn INTEGER NULL;"
    Et �a ne change rien alors que

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    currentdb.Execute "ALTER TABLE myTable ALTER COLUMN myColumn INTEGER NOT NULL;"
    Met la propri�t� "Required" au champ sans prob�me.

  4. #4
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    J'ignore si cette syntaxe existe en ACCESS
    Code sql : S�lectionner tout - Visualiser dans une fen�tre � part
    ALTER TABLE myTable ALTER COLUMN myColumn DROP NOT NULL
    essaye aussi sans le sp�cificateur
    Code sql : S�lectionner tout - Visualiser dans une fen�tre � part
    ALTER TABLE myTable ALTER COLUMN myColumn INTEGER
    sur la MSDN, NOT NULL existe mais pas NULL seul !
    Code sql : S�lectionner tout - Visualiser dans une fen�tre � part
    ALTER TABLE table {ADD {COLUMN field type[(size)] [NOT NULL]     [CONSTRAINT index] |     ALTER COLUMN field type[(size)] |     CONSTRAINT multifieldindex} |     DROP {COLUMN field I CONSTRAINT indexname} }
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre chevronn�

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par d�faut
    Bonjour ShaiLeTroll,

    Merci pour tes propositions, je les ai essay�es directement depuis la console d'Access mais elles ne fonctionnent malheureusement pas (erreur de syntax dans la requ�te lorsqu'on fait le "DROP NOT NULL" et aucun changement avec la premi�re syntaxe) :-(

    Patrick

  6. #6
    Membre chevronn�

    Profil pro
    Inscrit en
    D�cembre 2004
    Messages
    531
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2004
    Messages : 531
    Par d�faut
    Citation Envoy� par Patrick Seuret Voir le message
    Bonjour Blondelle,

    Merci pour ta proposition, mais je n'ai pas l'impression que c'est �a car ma base n'est pas prot�g�e (j'arrive � changer le flag manuellement depuis Access et aussi � renommer des colonnes avec ADOX comme dans mon code).

    Sinon, pour information, concernant la m�thode 1, j'ai essay� d'ex�cuter la commande suivant depuis Access:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    currentdb.Execute "ALTER TABLE myTable ALTER COLUMN myColumn INTEGER NULL;"
    Et �a ne change rien alors que

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    currentdb.Execute "ALTER TABLE myTable ALTER COLUMN myColumn INTEGER NOT NULL;"
    Met la propri�t� "Required" au champ sans prob�me.

    Bonjour, je note le m�me probl�me que toi sous Access 2007, donc avec un AdoQuery cela donne la m�me chose �vidamment.
    P� facile ton truc, peut �tre cr�ation d'une table temporaire dynamique et recopie avant de constituer l'origine, mais bonjours les d�lais..

    A voir aussi en OLE., mais je ne vois pas..

  7. #7
    Membre chevronn�

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par d�faut
    Oui, le Ole semblait prometteur car des forums semblaient indiquer que �a marche en ADOX (mais sous VBA dans les exemples que j'ai trouv�s, voir mes r�f�rences dans le code), mais �a plante chez moi

    Je me suis demand� si ma syntaxe pour modifier la valeur d'une propri�t� est bonne:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    column.OlePropertyGet("Properties")
           .OlePropertyGet("Item","Nullable")
           .OlePropertySet("Value",true); // aussi essayé avec "True"
    Mais comme le getter fonctionne, je ne vois pas pourquoi �a n'irait pas... En plus j'utilise un code similaire pour changer le nom de la colonne si n�cessaire et �a marche (enfin, marchait, du vieux code que je devrais peut-�tre v�rifier):
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    column.OlePropertySet("Name",newName);

  8. #8
    R�dacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par d�faut
    Peu etre en executant une Macro comme decrit ici

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo