3

I am using MS-SQL Server 2014 on Windows 7.
In the database, I currently have a table named "STATUS" where a column is defined like:

DeviceSerial   smallint

There are/will be more than 6k records in this table.
Unfortunately some devices were programmed with wrong serial numbers, for example 43776 instead of 4376 (the tech guy typed 7 twice...). Normally, the DeviceSerial value should be in range: 1 - 9999.
Obviously, 43776 is an out-of-range value for a smallint, hence the insert/update operation crashes :(

Well, the question is: In such situation(s), is there a way to do make the sql-server check the inserted/updated value and, if the DeviceSerial value is greater than 9999, put 0 for it? (0 would mean serial number not set or something).

סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68

3 Answers3

2

You can use a Contraint in your table, that way if someone try to update or insert a value out of the range you get an error. It would mantain your database with the rigth data, and won't have a problem with devices without serials later.

ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
   DeviceSerial   >= 1 AND DeviceSerial   <= 9999--Inclusive
)

or

ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
  DeviceSerial  BETWEEN 1 AND 9999  
)
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
Luis Tellez
  • 2,785
  • 1
  • 20
  • 28
  • And I think its a better idea to not insert incongruent data in a database, and thats what I'm suggesting. – Luis Tellez Mar 02 '16 at 13:50
  • Thanks for the idea. Yet, it would be better to have some sort of auto-correct... I know it is not possible to have a real auto-correct, but at least I would like to have a 0 (zero) instead :) For the reason(s) explained above. – סטנלי גרונן Mar 02 '16 at 13:59
  • @groenhen, although you could "auto-correct" bad data using a trigger, I think it would be better to validate and reject bad data instead of silently fixing it. – Dan Guzman Mar 02 '16 at 14:01
  • @DanGuzman: Nice thing with the trigger. Even better if you can add an explanation as regular answer :) I would surely be interested and appreciate it :) Thx in advance! – סטנלי גרונן Mar 02 '16 at 14:08
2

If you have SQL Server 2012+ you can use TRYPARSE or TRYCONVERT.

If TRYPARSE cannot convert the entered value to the requested datatype, it returns NULL, which can be coalesced to zero.

So if you were trying to insert @MyVariable into a smallint, you could put this in your insert statement:

COALESCE(TRYPARSE(@MyVariable AS smallint),0)

The insert will not error, and a zero will be inserted if the value cannot be inserted into a smallint column.

If you want to enforce not only that a value is in the smallint range but is in the specific range 1-9999, you can do it with a CASE expression:

CASE WHEN @MyVariable BETWEEN 1 AND 9999 THEN @MyVariable ELSE 0 END
Tab Alleman
  • 31,483
  • 7
  • 36
  • 52
0

There you go with a super-solution:

ALTER TABLE dbo.Status ALTER COLUMN DeviceSerial int NOT NULL

does not throw exception, lets you fix numbers any time you want, and you don't have to program any pseudo-views with instead-of triggers or stored proc with rewriting calls from client-side.

And this is a rare case where I'd suggest to use strings instead of numeric values. Serial number usually means a unique set of characters which may be digits and letters. And often it may have leading zero which means nothing for numeric values but is a regular and persistent part of a unique string.

Ivan Starostin
  • 8,798
  • 5
  • 21
  • 39