In realtà non c'è niente di sbagliato nella tua prima query, dal punto di vista sintattico è perfetto come dimostra questo esempio funzionante.
mysql> SET @@SESSION.block_encryption_mode = 'aes-256-cbc';
mysql> create table MyTable(
-> Encrypted_ID varbinary(256),
-> InitializationVector_iv varbinary(16)
-> );
Query OK, 0 rows affected (0.93 sec)
mysql> SET @iv = RANDOM_BYTES(16);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO MyTable SET Encrypted_ID = AES_ENCRYPT('hello','key', @iv), InitializationVector_iv = @iv;
Query OK, 1 row affected (0.17 sec)
mysql> SELECT CAST(AES_DECRYPT(Encrypted_ID,'key', InitializationVector_iv) AS CHAR) from MyTable;
+------------------------------------------------------------------------+
| CAST(AES_DECRYPT(Encrypted_ID,'key', InitializationVector_iv) AS CHAR) |
+------------------------------------------------------------------------+
| hello |
+------------------------------------------------------------------------+
1 row in set (0.00 sec)
Per quanto riguarda il motivo per cui non funziona, sono riuscito a ottenere la query per restituire NULL in 2 scenari. Uno, ottieni NULL restituito se usi un iv diverso per la crittografia e la decrittografia, quindi potresti voler guardare come stai archiviando come iv. Due, ottieni NULL dove hai la variabile block_encryption_mode impostata in modo diverso durante la memorizzazione e il tentativo di recuperare il valore, controlla che non stai ripristinando accidentalmente il valore predefinito 'aes-128-ebc tra le sessioni. Potrebbero essercene altri...
La seconda query fallirà perché è necessario fornire l'iv a entrambe le funzioni di crittografia e decrittografia, lo si utilizza solo per crittografare. Inoltre, poiché stai prendendo i valori da MyTable, Encrypted_ID sarà già crittografato e l'effetto di questa query sarebbe di crittografarlo nuovamente, prima di invertirlo per tornare al valore memorizzato (crittografato).
Infine, AES utilizzerà solo 16 byte di iv, quindi potresti anche farlo VARBINARY(16).