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:
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();
} |