HTML Web SQL DELETE

Beginner
⏱️ ~10–12 min
📚 Updated: Aug 2026
🎯 5 Examples
🚀 5 Try-it labs
DELETE · WHERE · rowsAffected

What You’ll Learn

Web SQL Database is a deprecated browser API that stores structured data in a local SQLite database. The SQL DELETE statement removes rows you no longer need—cleared cart items, revoked sessions, or outdated cache entries. This tutorial covers DELETE syntax, targeting rows with WHERE, binding safe parameters, checking rowsAffected, handling errors, five worked examples, and why Web SQL is deprecated in favor of IndexedDB.

DELETE

Core statement

Remove rows from a table with a standard SQL DELETE FROM statement.

WHERE

Target rows

Filter exactly which rows are removed—omit it and the whole table empties.

? bindings

Safe params

Bind ids and values with ? placeholders instead of concatenating SQL.

rowsAffected

Verify removal

Confirm how many rows were actually deleted—zero means no match.

Errors

Handle failure

Catch SQL errors in the failure callback and roll back safely.

Transactions

Atomic ops

Every executeSql call runs inside db.transaction().

Introduction

Web SQL Database is a deprecated browser API for client-side relational storage. It uses SQLite under the hood, so standard SQL statements—including DELETE—work just like they do on server-side databases.

The W3C deprecated Web SQL in favor of IndexedDB, and Chrome removed it in version 97. Although the API is no longer recommended for new projects, understanding DELETE still helps you maintain legacy applications and grasp the SQL fundamentals that carry over to other databases.

Why it matters?

Every app eventually needs to remove data—a cart item, a stale cache row, a logged-out session. DELETE is the only way to do that in a SQL database, but done carelessly it is also the easiest way to destroy data you meant to keep.

Key Highlights

Removes Rows

Permanently deletes matching rows from a table—there is no built-in undo.

WHERE Required

Always target rows with WHERE—without it, the entire table empties.

Bound Parameters

? placeholders keep dynamic values safe from SQL injection.

Deprecated API

Web SQL is educational for legacy code—use IndexedDB for new work.

In short: DELETE FROM table WHERE condition, bound with ?, inside a transaction, checked with rowsAffected—that pattern removes rows safely in Web SQL and in most SQL databases.

Understanding Web SQL Schema

Before deleting records, know which table and columns hold your data. A clear schema means your WHERE clause targets the correct rows.

js
const db = openDatabase('myDatabase', '1.0', 'Test DB', 2 * 1024 * 1024);

db.transaction(function (tx) {
  tx.executeSql(
    'CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)'
  );
  tx.executeSql(
    'INSERT OR IGNORE INTO items (id, name) VALUES (?, ?)',
    [1, 'Sample Record']
  );
});

This creates an items table with id and name, then seeds one row so you have something to delete in the examples below.

📝 DELETE Syntax

Standard SQL syntax for removing rows:

SQL
DELETE FROM table_name WHERE condition;

In Web SQL, call it through executeSql with bound parameters:

js
tx.executeSql(
  'DELETE FROM items WHERE id = ?',
  [id],
  function (tx, result) { /* success */ },
  function (tx, error)  { /* failure */ }
);

executeSql arguments

ArgumentDescription
sqlStatementThe DELETE FROM ... WHERE ... string, with ? placeholders for dynamic values.
argumentsArray of values bound to each ?, in order—e.g. [id].
successCallback (optional)Called as (tx, result); inspect result.rowsAffected.
errorCallback (optional)Called as (tx, error); return true to roll back the transaction.

Important rules

  • Always use WHERE when deleting specific rows—without it, every row in the table is removed.
  • Bind values with ? — never concatenate user input into the SQL string.
  • Check result.rowsAffected — zero means no row matched.
  • Deletes are permanent — confirm destructive actions in your UI.

⚡ Quick Reference

OperationCode pattern
Delete one rowDELETE FROM t WHERE id = ?
Delete by nameDELETE FROM t WHERE name = ?
Verify successresult.rowsAffected > 0
No matchrowsAffected === 0 — row not found
Delete all rowsDELETE FROM t (no WHERE — dangerous)
Target
WHERE id = ?

One row

Safe
[id]

? binding

Check
rowsAffected

Confirm hit

Wrapper
db.transaction()

Required

📋 DELETE vs UPDATE vs Clearing All Rows

All three change existing data—but they solve different problems.

DELETE
removes rows

Drops matching rows entirely—the row and its data are gone.

UPDATE
edits rows

Keeps the row but changes column values—use when data should stay, just change.

Clear all
DELETE FROM t

No WHERE empties the whole table but keeps its schema—rarely what you want by accident.

See the full UPDATE tutorial when you need to modify rows instead of removing them.

Context

When to Delete Rows

Reach for DELETE whenever data should genuinely disappear, not just change.

  1. Remove a cart item

    The shopper clicks “remove”—delete that row by id, not the whole cart.

  2. Logout cleanup

    Wipe session or token rows on sign-out so stale credentials cannot be reused.

  3. Cache and draft expiry

    Delete rows older than a timestamp, or discard unsaved drafts the user abandoned.

  4. Bulk cleanup by condition

    Clear all completed tasks or all rows matching a status with one WHERE clause.

  5. Not casually, without WHERE

    Never run DELETE FROM table_name without a condition unless you truly mean to empty it.

Key benefit: a precise WHERE clause removes exactly the rows you intend—nothing more, nothing less.

Deleting Records

The DELETE statement removes rows that match your WHERE condition. Wrap the logic in a reusable function:

js
function deleteRecord(id) {
  db.transaction(function (tx) {
    tx.executeSql(
      'DELETE FROM items WHERE id = ?',
      [id],
      function (tx, result) {
        console.log('Deleted rows:', result.rowsAffected);
      },
      function (tx, error) {
        console.error('Delete error:', error.message);
        return true;
      }
    );
  });
}

deleteRecord(1);
  • openDatabase — opens or creates the Web SQL database.
  • transaction — wraps the delete in an atomic unit.
  • executeSql — runs DELETE FROM ... WHERE id = ? with bound parameters.

Handling Deletion Errors

Errors can come from invalid SQL, missing tables, or constraint issues. A delete can also “succeed” with rowsAffected === 0 when no row matched—treat that separately from a real error.

js
tx.executeSql(
  'DELETE FROM items WHERE id = ?',
  [id],
  function (tx, result) {
    if (result.rowsAffected === 0) {
      console.warn('No row deleted — id may not exist.');
    } else {
      console.log('Record deleted successfully.');
    }
  },
  function (tx, error) {
    console.error('Error deleting record:', error.message);
    return true;
  }
);

Examples Gallery

These examples use the Web SQL API pattern. Use the Try It Yourself links to run live demos. Web SQL works only in browsers that still expose openDatabase; otherwise the demo shows a clear status message.

📚 Getting Started

Delete a single row by id with bound parameters.

Example 1 — Delete a Single Row

Remove the item with id = 1 from the items table.

js
const db = openDatabase('myDatabase', '1.0', 'Test DB', 2 * 1024 * 1024);

db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)');
  tx.executeSql('INSERT OR IGNORE INTO items (id, name) VALUES (?, ?)', [1, 'Sample Record']);

  tx.executeSql(
    'DELETE FROM items WHERE id = ?',
    [1],
    function (tx, result) {
      console.log('Deleted rows:', result.rowsAffected);
    },
    function (tx, error) {
      console.error('Error:', error.message);
    }
  );
});
Try It Yourself

How It Works

The transaction seeds a row, then deletes it. rowsAffected returns 1 when exactly one row was removed.

Example 2 — Reusable deleteRecord Function

Call the same function from buttons, list items, or swipe-to-delete handlers.

js
function deleteRecord(id) {
  db.transaction(function (tx) {
    tx.executeSql(
      'DELETE FROM items WHERE id = ?',
      [id],
      function (tx, result) {
        console.log('Deleted', result.rowsAffected, 'row(s) for id', id);
      },
      function (tx, error) {
        console.error('Delete error:', error.message);
        return true;
      }
    );
  });
}

deleteRecord(1);
deleteRecord(99); /* id 99 does not exist */
Try It Yourself

How It Works

The second call returns 0 rows when id 99 was never inserted—not an error, but worth reporting to the user.

📈 Practical Patterns

Verify deletions, delete by condition, and build a complete demo page.

Example 3 — Detect When No Row Matches

Use rowsAffected to warn when the target id does not exist.

js
function deleteItem(id) {
  db.transaction(function (tx) {
    tx.executeSql(
      'DELETE FROM items WHERE id = ?',
      [id],
      function (tx, result) {
        if (result.rowsAffected === 0) {
          console.warn('No item with id', id);
        } else {
          console.log('Removed item', id);
        }
      }
    );
  });
}

deleteItem(42); /* does not exist */
Try It Yourself

How It Works

Deleting a missing id does not throw an error—it succeeds with zero rows affected. Your UI should distinguish “not found” from “deleted.”

Example 4 — Delete by Condition

Remove all rows matching a column value—for example, clear completed tasks.

js
/* table: tasks (id, title, done INTEGER 0/1) */

function deleteCompletedTasks() {
  db.transaction(function (tx) {
    tx.executeSql(
      'DELETE FROM tasks WHERE done = ?',
      [1],
      function (tx, result) {
        console.log('Cleared', result.rowsAffected, 'completed task(s)');
      }
    );
  });
}
Try It Yourself

How It Works

WHERE done = ? can match multiple rows. rowsAffected reports the total number removed. Double-check your condition before running bulk deletes.

Example 5 — Complete HTML Page

Set up the database, seed a row, and delete it with a button click.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Web SQL Delete Example</title>
</head>
<body>
  <h1>Delete Records from Web SQL</h1>
  <button type="button" id="deleteBtn">Delete Record with ID 1</button>
  <p id="status"></p>

  <script>
    if (!window.openDatabase) {
      document.getElementById('status').textContent =
        'Web SQL is not supported in this browser.';
    } else {
      const db = openDatabase('myDatabase', '1.0', 'Test DB', 2 * 1024 * 1024);

      db.transaction(function (tx) {
        tx.executeSql(
          'CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)'
        );
        tx.executeSql(
          'INSERT OR IGNORE INTO items (id, name) VALUES (?, ?)',
          [1, 'Sample Record']
        );
      });

      document.getElementById('deleteBtn').addEventListener('click', function () {
        deleteRecord(1);
      });

      function deleteRecord(id) {
        db.transaction(function (tx) {
          tx.executeSql(
            'DELETE FROM items WHERE id = ?',
            [id],
            function (tx, result) {
              document.getElementById('status').textContent =
                result.rowsAffected
                  ? 'Deleted id ' + id
                  : 'No row found for id ' + id;
            },
            function (tx, error) {
              document.getElementById('status').textContent =
                'Error: ' + error.message;
              return true;
            }
          );
        });
      }
    }
  </script>
</body>
</html>
Try It Yourself

How It Works

The page seeds id 1 on load. Clicking the button runs deleteRecord(1) and updates the status text on the page.

Use Cases

Real-world scenarios where removing rows is exactly what you need.

1. Clear Cart Items

Remove products the user removed from their basket.

Example: DELETE FROM cart WHERE product_id = ?.

2. Delete Drafts

Discard unsaved notes or form drafts the user chose not to keep.

Example: a “discard draft” button in an editor.

3. Logout Cleanup

Wipe session or token rows on sign-out for security.

Example: DELETE FROM sessions WHERE user_id = ?.

4. Cache Expiry

Delete stale rows older than a timestamp to keep storage fresh.

Example: DELETE FROM cache WHERE expires_at < ?.

5. Bulk Task Cleanup

Clear every row matching a condition, like all completed tasks.

Example: DELETE FROM tasks WHERE done = 1.

6. Legacy Maintenance

Purge records in older Web SQL–based apps still running in the wild.

Example: a support script cleaning orphaned rows.

Pro Tip: pair every delete with a SELECT during development so you can preview exactly which rows a WHERE clause will match.

Advantages

Why the standard SQL DELETE pattern is worth learning, even in a deprecated API.

  1. 1. Precise Targeting

    WHERE removes exactly the rows you specify—nothing implicit.

  2. 2. Safe by Default

    ? bindings sanitize values automatically, avoiding SQL injection.

  3. 3. Auditable Results

    rowsAffected tells you exactly how many rows changed—no guessing.

  4. 4. Transactional Atomicity

    Wrapped in db.transaction(), related statements succeed or fail together.

Pro Tip: this exact pattern—WHERE, bound parameters, transactions, and checking affected rows—transfers directly to IndexedDB, SQLite, and server-side SQL.

Usage Tips

Follow these practices to write safe, predictable deletes.

  1. 1. Preview With SELECT First

    Run the equivalent SELECT ... WHERE ... to confirm which rows will be removed before you delete.

  2. 2. Always Check rowsAffected

    Zero means no match—update your UI to say “not found,” not “deleted.”

  3. 3. Bind Every Dynamic Value

    Use ? placeholders for ids, names, and conditions—never build SQL with string concatenation.

  4. 4. Confirm Destructive Actions

    Ask the user to confirm before running a delete that cannot be undone.

  5. 5. Plan Your Migration to IndexedDB

    Web SQL is deprecated—treat new features as an opportunity to move to IndexedDB.

Pro Tip: log every delete’s SQL, bound values, and rowsAffected during development—it turns “why did that disappear?” bugs into a quick log lookup.

Common Pitfalls

Avoid these mistakes when removing rows with Web SQL.

  1. 1. DELETE Without WHERE

    Forgetting the condition empties the entire table instantly, with no confirmation.

    → Always double-check for a WHERE clause before running a delete.

  2. 2. Concatenating SQL Strings

    Building queries with string concatenation opens the door to SQL injection.

    → Bind every dynamic value with ? placeholders instead.

  3. 3. Ignoring rowsAffected

    Treating every callback as success hides “row not found” cases from your users.

    → Check result.rowsAffected and branch your UI message accordingly.

  4. 4. Assuming Web SQL Works in Modern Chrome

    Chrome removed Web SQL in version 97—code that assumes openDatabase exists will crash.

    → Feature-detect with if (window.openDatabase) before running any Web SQL code.

  5. 5. Expecting an Undo

    Once a transaction commits, deleted rows are gone—there is no built-in recovery.

    → Confirm destructive actions in the UI, or keep a backup before deleting.

Pro Tip: when in doubt, run the same condition as a SELECT first—if the preview looks right, the delete will too.

🧠 How Web SQL DELETE Works

1

Open & transact

openDatabase() then db.transaction() starts an atomic unit of work.

Setup
2

Match rows

WHERE id = ? selects rows to remove.

Filter
3

Run DELETE & commit

executeSql removes matches; the transaction commits the change.

Remove
=

Row removed

rowsAffected reports how many rows were deleted.

Notes

  • Web SQL is deprecated and removed from modern Chrome—use IndexedDB for any new project.
  • Always include WHERE unless you intentionally mean to clear the entire table.
  • Check rowsAffected—zero means no match, not necessarily an error.
  • Bind all dynamic values with ? placeholders—never string-concatenate SQL.
  • Deletes cannot be undone after the transaction commits.
  • Pair with SELECT to confirm what will be deleted first.

Quick Takeaway: Web SQL is deprecated—practice DELETE here to learn the pattern, then apply the same WHERE + bindings + rowsAffected habits in IndexedDB and other SQL databases.

Browser Support

Web SQL was never implemented in Firefox or Internet Explorer. Chrome and other Chromium browsers removed it in Chrome 97. Only older Safari versions historically supported it. Feature-detect with window.openDatabase before running any demo or legacy code.

Deprecated

Web SQL API

Web SQL is not part of any current web standard. Modern Chrome, Edge, and Opera have removed it entirely; Firefox never implemented it. Treat this tutorial as educational for legacy maintenance only.

Legacy Not in modern browsers
Google Chrome Removed in Chrome 97+
Removed
Mozilla Firefox Never implemented
Not supported
Apple Safari Legacy versions only
Legacy
Microsoft Edge Chromium-based · removed
Removed
Internet Explorer Never implemented
Not supported
Opera Chromium-based · removed
Removed
Web SQL API Deprecated

Bottom line: Do not build new features on Web SQL. For cross-browser client-side storage today, use IndexedDB.

Wrap Up

🎉 Conclusion

Deleting records with Web SQL means running DELETE FROM ... WHERE ... inside db.transaction, binding values safely with ?, and checking rowsAffected to confirm the right rows were removed.

Although Web SQL is deprecated, understanding deletes helps you maintain older systems. For new projects, use IndexedDB—but the SQL habits you learned here (safe parameters, WHERE clauses, and row counts) apply everywhere.

Practice the five examples above, then continue to INSERT so you always have fresh rows to delete.

💡 Best Practices

✅ Do

  • Use WHERE to target specific rows
  • Bind values with ? placeholders
  • Check result.rowsAffected after every delete
  • Confirm destructive actions in the UI
  • Handle error callbacks and return true to roll back
  • Prefer IndexedDB for new projects

❌ Don’t

  • Omit WHERE unless you mean to wipe the table
  • Concatenate user input into SQL strings
  • Assume success when rowsAffected is 0
  • Delete without user confirmation for important data
  • Skip transactions around executeSql calls
  • Build new features on Web SQL in 2026

Key Takeaways

Knowledge Unlocked

Five things to remember about Web SQL DELETE

Use these points when removing rows from a client-side database.

5
Core concepts
🎯 02

WHERE

Target id.

Filter
🔒 03

? bindings

Safe params.

Security
🔢 04

rowsAffected

Verify hit.

Reliability
⚠️ 05

Permanent

Confirm first.

Safety

❓ Frequently Asked Questions

Open the database with openDatabase(), then call db.transaction(). Inside the transaction, use tx.executeSql() with DELETE FROM table_name WHERE condition. Bind the id or filter values with ? placeholders: DELETE FROM items WHERE id = ?
Standard SQL: DELETE FROM table_name WHERE condition. Always use WHERE when deleting specific rows—DELETE FROM table_name without WHERE removes every row in the table.
Check result.rowsAffected in the success callback. If it is 0, no row matched your WHERE clause (wrong id or already deleted).
Web SQL requires all executeSql calls within db.transaction(). Transactions keep operations atomic—if a related statement fails, changes can roll back together.
Web SQL is deprecated and removed from most modern browsers (including current Chrome). Treat this tutorial as educational for legacy code; use IndexedDB for new projects.
No. Once a transaction commits, deleted rows are gone unless you kept a backup or can re-fetch from a server. Confirm destructive actions in your UI before deleting.

Did you Know? 🔊

DELETE FROM table_name without a WHERE clause removes every row in the table but keeps the table structure — faster than dropping and recreating the table when you want an empty slate with the same schema. Because Web SQL is deprecated, treat every DELETE you write here as a rehearsal for the same pattern in IndexedDB.

Continue to Web SQL INSERT

Now that you can remove rows, learn how to add new ones so there is always fresh data to work with.

INSERT tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful