You can't delete records before they're saved to the database (for lack of a better word), and that doesn't happen until just before an after insert
trigger would fire.
Records being inserted are also not able to be queried until they are assigned an Id (which also happens just before an after insert
trigger would fire).
If you're looking to handle situations where people are entering these records one at a time, then a validation rule would be a much better choice (stop bad data before it gets saved!).
If you're inserting these records from some other trigger or apex class, then you should be preventing the records you'd end up deleting from even attempting to be inserted in the first place.
e.g.
List<hed__Program_Enrollment__c> recordsToInsert = new List<hed__Program_Enrollment__c>();
for(SomeObject__c someRecord :[SELECT <some fields> FROM SomeObject__c WHERE <filters>]){
hed__Program_Enrollment__c enrollment = createEnrollment(someRecord);
if(enrollment.Flag__c = 'X'){
// skip this record, and move on to the next iteration of the loop
continue;
}
recordsToInsert.add(enrollment);
}
insert recordsToInsert;
+edit:
On a second reading, it seems like your records do not initially have this flag set to 'X', but that's happening in a separate update (through some process).
If that's the case, then you'd want to use the after update
context to your trigger (you really should be using a trigger framework, but that's out of scope for your question), iterating through a trigger context variable to figure out which records should be deleted (adding them to a list), and then deleting them (no queries required).
Given your current trigger structure, such a trigger could look like
// Best practice is to have only a single trigger on any given object
// A single trigger can be run in different contexts by adding multiple contexts
// inside the "()", separated with commas
trigger MyTrigger on MyObject__c (before insert, after update){
// You can do specific work in each context by checking
// - Trigger.isBefore
// - Trigger.isAfter
// - Trigger.isInsert (or isUpdate, isDelete, isUndelete)
// - Trigger.operationType
// Best practice is also to use a trigger framework and keep logic outside
// of the trigger itself.
// I'm not going to go over that, but breaking your work into specific events
// like this will make that transition easier/more intuitive
switch on Trigger.operationType{
when System.TriggerOperation.BEFORE_INSERT{
// do work to modify data before it's inserted so you can
// avoid needing to do a DML update
}
when System.TriggerOperation.AFTER_UPDATE{
List<SObject> recordsToDelete = new List<SObject>();
for(MyObject__c myRecord :trigger.new){
if(myRecord.Flag__c == 'X'){
recordsToDelete.add(myRecord);
}
}
delete recordsToDelete;
}
}
}