Your SELECT Is Lying to You
Your SELECT returns one thing. SE16 shows another. The data in the database is correct, but your program disagrees.
This is not a bug in your code. It is the table buffer doing exactly what it was designed to do.
What happens
SAP buffers table contents on the application server to reduce database round-trips. When you run a SELECT without any special additions, ABAP may serve the result from this local cache instead of hitting the database.
Under normal operations, the buffer stays reasonably in sync. But after certain events (client copies, system copies, mass data changes, or when individual app servers fall behind on cache invalidation), the buffered data can go stale. Your program reads the buffer. SE16 reads the database. They disagree.
How to confirm it
Run your query with BYPASSING BUFFER:
SELECT * FROM ztable
INTO TABLE @lt_data
BYPASSING BUFFER.
If this returns different (correct) data, the table buffer is the problem.
SE16 reads directly from the database, bypassing the buffer implicitly. That is why it shows current values while your program may not.
How to fix it
In the SAP GUI OK-Code field, execute:
/$SYNC
This resets the application server's buffers (table buffer, nametab, program buffer, and others). The server rebuilds its cache from the database on subsequent access.
In a multi-server landscape, run /$SYNC on each application server, or coordinate a controlled restart. Keep in mind that resetting buffers temporarily lowers cache hit rates until the buffer warms up again.
When to worry
If this happens once after a client copy, it is expected behavior. The copy changed data underneath the buffer without going through the normal invalidation path.
If it keeps happening during regular operations, something else is off. Look at the buffering settings on the table (SE13), check whether the table should be buffered at all for your use case, and verify that DBTABLOG and buffer synchronization are working across your landscape.