6

Update:

Here is what I have learned from the answers below...

SQLite supports defining default values on columns. However, it does not support any form of DEFAULT keyword or function in queries. So, in effect, it is not possible to do a MySQL style bulk insert where a column is set explicitly in some rows, and the column default is used in other rows.

There are several creative workarounds listed below, but for simplicity's sake I most prefer Shawn's suggestion of using an INSERT statement per row, possibly all wrapped inside a BEGIN TRANSACTION statement. Only this will allow you to utilize column defaults.


Original Question:

I have a simple SQLite table named todo with this schema...

schema

I can insert rows into this table with this syntax...

INSERT INTO 'todo' ('title', 'complete', 'notes') VALUES
  ('Pickup dry cleaning', true, 'They close at 7pm'),
  ('Clean apartment', false, 'Floors have already been swept'),
  ('Finish homework', true, 'Chapters 3 and 4');

However,

I can't figure out how to omit certain values and let the database use the default for that column.

For example, the complete column has a default of 0. It would be nice to be able to pass undefined as one of the values in my query, thus signaling to SQLite that I'd like to use whatever the column default is, but I get a Result: no such column: undefined error when I try this.

null would not work in this case either, because sometimes you want to explicitly set the value of a cell to null. You can't just plain omit the value either because the parameters are positional.

1
  • FYI PostgreSQL, Microsoft SQL and Oracle, as well as MySQL and MariaDB all support the DEFAULT keyword. It’s not called SQLite for nothing. I suppose the hosting application is expected to sort that out. Commented Mar 18, 2023 at 2:19

4 Answers 4

8

You just leave it out of the columns being inserted:

INSERT INTO todo(title, notes) VALUES ('Music practice', 'Not Elvis');
Sign up to request clarification or add additional context in comments.

3 Comments

Shawn, I guess the issue with this solution is that I don't think it would work with multiple rows (i.e. bulk insert) where in some rows you want to explicitly set the value of a column, but in other rows you want to use the default.
@J.Munson Use different insert statements for different combinations of values being inserted.
For other people searching this you can enter all values as default like this: INSERT INTO todo DEFAULT VALUES;
1

I can't figure out how to omit certain values and let the database use the default for that column.

As of this writing, SQLite does not support the default(_) function, but you could use triggers to achieve the effect you want, though doing so is a bit cumbersome.

Here's an example:

CREATE TRIGGER IF NOT EXISTS onnull
AFTER INSERT ON mytable
FOR EACH ROW
WHEN NEW.column = 'undefined'
BEGIN
    UPDATE mytable 
    SET column = 'mydefault' 
    WHERE rowid=NEW.rowid ;
END;

——

Footnote: one can determine the DEFAULT value by:

SELECT dflt_value
FROM pragma_table_info('mytable')
WHERE name = 'column';

So (still using 'column' and 'mytable' to represent respectively the column name and table of interest) you could write:

CREATE TRIGGER IF NOT EXISTS onnull
AFTER INSERT ON mytable
FOR EACH ROW
WHEN NEW.column = 'undefined'
BEGIN
    UPDATE mytable 
    SET column = (SELECT dflt_value
      FROM pragma_table_info('mytable')
      WHERE name = 'column')
    WHERE rowid=NEW.rowid ;
END;

5 Comments

Good solution. I don’t want to tamper with your answer, but I think it would make sense to use the string 'default' to resemble the behavior other DBMS.
'mydefault' is only meant as a placeholder for whatever default value is appropriate.
No, I meant the undefined string. In other SQLs the dummy value is DEFAULT.
The Q specifically asked for a trigger on undefined: “ It would be nice to be able to pass undefined as one of the values in my query”
out of curiousity why is it necessary to do a full UPDATE query just to find the field to update, when we already have the new record in NEW? Why not just do: "NEW.column='mydefault'"? It seems valid syntax as I don't get any errors when I try this, but afterwards the column value isn't properly set even if the trigger is BEFORE INSERT.
0

this works if you are using better-sqlite3, and I think it will equally work for sqlite3.

db.prepare("INSERT INTO bugs (title, notes) VALUES (?, ?)").run(["Good Book", "nice test"]);

Comments

-1

What Shawn said plus the bulk issue can be solved with DEFAULT value, that is if you are inserting all records manually, if you want it dynamically through a loop for example you must declare a variable as default and change to the specific value if the specific value exists, and use this variable in the query.

String var='DEFAULT';
if (Value exists) {var=Value;}

sql=inset into x(x,y,z) values (a,b,var);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.