1

I'm writing a lot of stored procedures for a SQL Server database that take an id or code that is a CHAR instead of an INT. Most of these haven't changed size in a long time, but when a customer wants to increase the size we generally do. This wouldn't be a problem except for the fact that any stored procedure with a parameter typed CHAR(4) would suddenly break.

I have three ideas for keeping the column sizes in one location, but I don't know if I like any of them. First is to simply use a type that is much larger than necessary, eg VARCHAR(100). Are there any negative consequences to this other than lack of clarity in the code?

Second is to have the scripts that generate the procedures look up the column size to dynamically define their variable types. This would be better, but I'm not sure it would be possible without a lot of dynamic SQL, and we'd still need to rerun all of the scripts when something changed.

Finally, whenever a script updates a column's size, it could also go and update all of the stored procedures referencing it. I like this the most, but in a big organization with many programmers it would be easy for someone to forget or to miss a procedure.

I know that using INT ids or an ORM would avoid the problem entirely, but unfortunately there's already a lot of code using the strings, and refactoring the database is not a business priority.

Justin Cave
12.8k3 gold badges48 silver badges54 bronze badges
asked Jul 20, 2016 at 18:07
3
  • 2
    What database are you using? In Oracle, the answer is to use anchored data types (table.column%type). But that is hardly universal across databases. Commented Jul 20, 2016 at 18:27
  • We're using SQL Server Commented Jul 20, 2016 at 18:34
  • Varchar(50) all the way Commented Jul 20, 2016 at 19:15

2 Answers 2

3

You must declare the variable as being of the type of a table's column. That way if the table column changes the stores procedure needs not change.

v_myvar owner.table.column%type;
answered Jul 20, 2016 at 18:18
2
  • Is this limited to certain DBMSs? It doesn't seem to be working for me in SQL Server. Commented Jul 20, 2016 at 19:28
  • 1
    @AndrewPiliser it's Oracle PL/SQL. Commented Jul 20, 2016 at 19:43
1

One drawback of using overly long columns is in run-time memory allocation. SQL Server will use half the declared length when calculating how much memory to request. So for varchar(100) it will be 50 bytes per value.

This may not be a problem if the server has sufficient RAM or such queries are infrequent. If, however, it is every row in every table in every query the overhead could mount up. There is a risk that operations which may otherwise be entirely in memory start spilling to disk, with obvious performance impact.

Variable-length columns carry around with then an additional hidden internal field holding the length of the actual data. Again this is small by itself but could contribute to memory pressure depending on workload and configuration.

T-SQL has no way of tying a variable's type to a column's meta data. An approach could be to declare an alias type and use it rigorously throughout your code. Changes would then be limited to the column(s) and the alias.

CREATE TYPE my_customer_id FROM char(4);

and

CREATE OR ALTER PROCEDURE This_Proc
 @Some_Id AS my_customer_id
AS
 ...

The problem is that a user defined type cannot be ALTERed. To increase the length you'll have to define a new type (my_customer_id_6 perhaps?) and replace all the existing references. Some kind people have published scripts to automate this. The benefit is that these references will be easily found.

answered Sep 11, 2019 at 11:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.