36

I’ve got an SQLite database that will need to contain products. Those products have a fixed-format composite product number, consisting of category, group and product number (cccccc.gg.ppp). Every time a new product is inserted, the new product number should be built using the category and group numbers, followed by the highest product number in that group incremented with one.

To that end, I was thinking of storing all three numbers in separate fields, and use a view to dynamically assemble the product number. For that to work, I would need to add leading zeroes, since the product number’s format is fixed.

However, I can’t seem to find a built-in SQLite function which would let me do this... :-(

I’d rather not write a custom function, since we might have to share the database with other developers, for them to read data from; and I have no idea what platform or language they’re going to use.

Can this be done? Or will we have to find a different solution?

5
  • In addition to the direct answer to your question from @9000, give some thought to whether the category, group, and product numbers shouldn't actually be stored as text. Commented Feb 6, 2011 at 21:06
  • Why should they be stored as text vs. as numbers? (Especially the product number, since I need to get its maximum value + 1 for the next product number).
    – Martijn
    Commented Feb 7, 2011 at 9:50
  • Text preserves leading zeroes. There's something to be said for storing "000123" when your requirement is to store "000123". Commented Feb 7, 2011 at 11:26
  • that is not the issue. I need to get the next value; which means having it available as number, and converting that to a zero-prefixed string. How it is stored is a separate issue entirely.
    – Martijn
    Commented Feb 7, 2011 at 14:34
  • You can cast strings to numbers to do arithmetic on them. See sqlite.org/lang_expr.html#castexpr Commented Feb 7, 2011 at 15:36

4 Answers 4

88

This can be accomplished with a little bit of magic using string concatenation and the substr function. Long story short, here's what you want:

select substr('0000000000'||'1234', -10, 10)

An explanation follows.

First, know that SQLite's string concatenation operator is ||.

We'll start by taking a string that is as long as the value we want to return. For example, if you want to return a number that is always 10 characters long and have it be left padded with 0s if it is shorter, then start with a string of ten 0s. To that, we will concatenate the number you want to return. In our example, that is '1234'. So far, we have the part that looks like this: '0000000000'||'1234'

Then, pass that whole thing into the substr function. According to the documentation, here's how the substr function works:

The substr(X,Y,Z) function returns a substring of input string X that begins with the Y-th character and which is Z characters long. ... If Y is negative then the first character of the substring is found by counting from the right rather than the left.

So if you want the string to be 10 characters long, pass -10 as the Y parameter (to start counting from the right, 10 characters back) and pass 10 as the Z parameter (to take 10 characters total).

0
32

Since 3.8.3 (2014) You can use printf as:

SELECT printf('%04d', product_number) AS product_number FROM table;

Change the 4 to however many digits you need. This would return 0001 for product_number 1.

2
  • 1
    I might add that using double quotes for string literals is discouraged and regretted in SQLite (see sqlite.org/…). The following expression is probably better: printf('%04d', product_number). Nice answer, though.
    – Manngo
    Commented Oct 18, 2019 at 1:45
  • Thanks @Manngo. I updated it to use the single quotes.
    – shao.lo
    Commented Oct 18, 2019 at 17:32
16

I know this is an old question, but the following is simpler:

--  zero-pad to 4 digits:
select substr('0000'||3,-4);

substr does not require a length if you’re selecting to the end.

12

select substr('0000000000'||'1234', length('0000000000'||'1234')-9, 10) works; substitute '1234' with your product number, any length <= 10.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.