WordPress Custom SQL Table with UserID Filter for results

The evolution of this question makes it difficult to succinctly answer, but in brief summary:

  • Using $wpdb->prepare() to construct arbitrary SQL queries to execute against the database helps to mitigate injection vulnerabilities by escaping inserted variables. To use it, instead of concatenating or directly inserting variables into the query, use a placeholder for the appropriate type of data, then pass the variable which be inserted in that location in a respectively indexed array as the second argument.
  • If this character data is input by end-users, you should also consider sanitizing the inputs prior to inserting them into the database, and possibly escaping the values prior to displaying them on the front-end to further mitigate the risk of injection vulnerability and to prevent end users from displaying arbitrary HTML/JavaScript when their character data is displayed.
  • Queries executed via $wpdb->get_results() return an array of objects, with the properties on the objects being named after the columns in the SQL table. If you prefer to work with arrays instead (either associative or numerically indexed) you can change this behavior by passing one of the predefined constants in as the second argument.
  • When printing a non-primative data structure such as an object, PHP won’t automatically serialize the object into a string for display. print_r() is capable of printing most common data structures, but var_dump() is a invaluable development aide when you’re not sure of the type of the value.

All of that said, since each object in the array represents one row from your database table and since HTML tables are constructed one row at a time, you can simply use a single foreach loop to place the relevant values from each item into a cell:

<?php
global $wpdb;
$uid = get_current_user_id();

$sql = $wpdb->prepare( "SELECT * FROM `sr3_characters` WHERE `wp_id` = %s", array( $uid ) );
$results = $wpdb->get_results( $sql );
?>
<html>
<body>
  <table border="1">
    <thead>
      <tr>
        <th scope="col">Name</th>
        <th scope="col">Race</th>
        <th scope="col">Gender</th>
        <th scope="col">Age</th>
      </tr>
    </thead>
    <tbody>
      <?php foreach( $results as $row ) { ?>
      <tr>
        <th scope="row"><?php echo esc_html( $row->char_name ); ?></th>
        <td><?php echo esc_html( $row->char_race ); ?></td>
        <td><?php echo $row->char_gender; ?></td>
        <td><?php echo $row->char_age; ?></td>
      </tr>
      <?php } ?>
    </tbody>
  </table>
</body>
</html>