GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Simulate query for UPDATE/DELETE – preview affected rows per SELECT · Issue #2646 · HeidiSQL/HeidiSQL

Simulate query for UPDATE/DELETE – preview affected rows per SELECT #2646

New issue
Copy link
New issue
Copy link
Open
Open
Simulate query for UPDATE/DELETE – preview affected rows per SELECT#2646
Copy link
Labels
confirmedIssue verified by project memberIssue verified by project memberfeatureA new feature to implementA new feature to implement

Description

@q2apro
q2apro
opened on Oct 29, 2026
Issue body actions

Is your feature request related to a problem? Please describe.
Before running an UPDATE or DELETE on a production database I want to see which rows it will touch, without writing anything. phpMyAdmin has a "Simulate query" button for exactly this. In HeidiSQL I have to rewrite the statement into a SELECT by hand, or wrap it in START TRANSACTION / ROLLBACK, every single time. Both are error-prone and slow for one-off maintenance queries.

Describe the solution you'd like
A new action "Simulate current query" next to "Explain current query" (Query menu, toolbar, shortcut). It rewrites the UPDATE/DELETE under the cursor into a read-only SELECT with the same FROM/JOIN and WHERE clause, runs it, and shows the result in a normal result tab with the row count in the status bar.

  • UPDATE: show the primary key, the current value of each SET column and the new value as an expression
  • DELETE: show the rows that would be removed
  • INSERT and DDL: out of scope

Example – input:
UPDATE t SET col = REPLACE(col, 'a', 'b') WHERE id > 100;

simulated as:
SELECT id, col, REPLACE(col, 'a', 'b') AS col_new FROM t WHERE id > 100;

Nothing is written, autocommit stays on, no transaction handling needed.

Describe alternatives you've considered

  • Manual rewrite to SELECT: works, but has to be done for every query.
  • START TRANSACTION ... ROLLBACK: works for DML, but is easy to forget half-way and does not cover implicit commits.
  • Keeping phpMyAdmin installed just for this one button.

Additional context
HeidiSQL 12.22.0.7382, MySQL 8.0.42. Checked the latest nightly, the feature does not exist there. Searched issues for "simulate", "dry run", "preview" – no existing request.

Activity

  1. q2apro commented on Oct 30, 2026

    @q2apro
    q2apro
    on Oct 30, 2026
    Author
    More actions

    A real example from today, to make the use case concrete. Column migration in six statements, flag bits moved into new columns and then cleared:

    UPDATE edu_boxes      SET ratingmode = CASE WHEN flags & 256 THEN 2 WHEN flags & 512 THEN 3 WHEN flags & 2 THEN 1 ELSE 0 END WHERE flags & 770;
    UPDATE edu_boxhistory SET ratingmode = CASE WHEN flags & 256 THEN 2 WHEN flags & 512 THEN 3 WHEN flags & 2 THEN 1 ELSE 0 END WHERE flags & 770;
    UPDATE edu_paths      SET widthmode  = CASE WHEN flags & 64 THEN 1 WHEN flags & 128 THEN 2 ELSE 0 END WHERE flags & 192;
    UPDATE edu_boxes      SET flags = flags & ~770 WHERE flags & 770;
    UPDATE edu_boxhistory SET flags = flags & ~770 WHERE flags & 770;
    UPDATE edu_paths      SET flags = flags & ~192 WHERE flags & 192;
    

    What I need / want before pressing CTRL+ENTER (or F9) is one result per statement:

    #  | Statement                               | Matched rows
    1  | UPDATE edu_boxes SET ratingmode ...     | 12 345
    2  | UPDATE edu_boxhistory SET ratingmode ...| 98 765
    ...
    

    i.e. "Simulate" applied to the whole tab (or selection), each UPDATE/DELETE rewritten to SELECT COUNT(*) FROM <table> WHERE <same where> and run read-only, like phpMyAdmin does for a single statement.

    Then the chance to have a wrong query deleting / changing your production server data is way lower. ⚠️ I once queried without simulate in phpmyadmin and forgot one char, which was overriding the entire data of all entries of one column of my table. Took me hours to get back the original data.

    Since then I always simulate first — so for me this is more than a nice-to-have.

    Today I write a hand-made SELECT ... UNION ALL ... with the three WHERE clauses copied over, which is longer than the migration itself and easy to get out of sync with the real statements.

    Known limitation, fine with me: each simulated SELECT runs against the current data, so statements that depend on an earlier one's effect (here 4–6 on 1–3) show pre-migration counts. That's still exactly the number I need to sanity-check the WHERE.

  2. ansgarbecker commented on Oct 30, 2026

    @ansgarbecker
    ansgarbecker
    on Oct 30, 2026
    Collaborator
    More actions

    There is already "Explain current query", which makes a deeper analysis and shows you index usage and more:

    Image

    On a side note: HeidiSQL is not imitating phpMyAdmin, it has its own usage concept.

  3. ansgarbecker
    added
    featureA new feature to implementA new feature to implement
    on Oct 30, 2026
  4. q2apro commented on Oct 30, 2026

    @q2apro
    q2apro
    on Oct 30, 2026
    Author
    More actions

    Thanks for the reply. I think the request got mixed up with EXPLAIN, so let me be more precise.

    EXPLAIN answers "how will the server execute this" – index usage, estimated rows, join order. That's a performance tool.

    What I'm asking for answers "which rows will this change, and what will they look like afterwards" – a correctness tool. EXPLAIN cannot show that: the row estimate is an estimate, and it never shows the actual key values or the before/after column values.

    Concrete example. Given

    UPDATE edu_eventlog SET params = REPLACE(params, '|p=x', '') WHERE event = 'box-aichange' AND params LIKE '%|p=x';
    

    EXPLAIN tells me "range scan on idx_event, ~1200 rows". What I need to see before I press F9 on a production database is

    id   | params (current)        | params (new)
    4711 | ...|p=foo|p=x           | ...|p=foo
    4712 | ...|p=x                 |
    ...  | (exact count: 1187 rows)
    

    i.e. a SELECT of the primary key, each SET column and its new expression, with the same FROM and WHERE. Nothing written, autocommit untouched.

    Forget the phpMyAdmin comparison – that was only meant as "this concept exists and works", not as "please copy it". The feature stands on its own: HeidiSQL already warns about UPDATE/DELETE without WHERE; this is the natural next step for the ones with a WHERE, where the danger is a wrong condition rather than a missing one.

    Would you be open to it as "Simulate current query" alongside "Explain current query", or as a PR?

  5. ansgarbecker
    changed the title [-]Simulate query for UPDATE/DELETE – preview affected rows like phpMyAdmin[/-] [+]Simulate query for UPDATE/DELETE – preview affected rows per SELECT[/+] on Oct 30, 2026
  6. ansgarbecker commented on Oct 30, 2026

    @ansgarbecker
    ansgarbecker
    on Oct 30, 2026
    Collaborator
    More actions

    No PR please for features. I will get into that myself. But yes, I'm open to that, thinking this could indeed help a few other users as well.

    Thank you for understanding. You wouldn't believe how many requests come in which tell about a feature in some other tool, and declare that tool as defacto standard, and HeidiSQL has to follow that concept. Glad this is not the case here.

  7. ansgarbecker
    added
    confirmedIssue verified by project memberIssue verified by project member
    on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmedIssue verified by project memberIssue verified by project memberfeatureA new feature to implementA new feature to implement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.