You can use the SPACE function to insert a number of spaces - or REPLICATE. The problem you are seeing is because LEN does not count trailing spaces. If you want to see the actual data length - use the function DATALENGTH.
To build a flat file record - you can do something like:
Select concat('x', space(9), 'x');
With that said - how are you outputting this data to a file?
I understand what you are doing - I was asking about the tool you are using to actually create the file. If you use SSIS then all of that is not necessary and will be handled by SSIS.
If you are using BCP or something else - then that is the easiest way to get it done.
If you look at my example using CONCAT - it does exactly what you want. However - you should only pad spaces where you are dealing with filler fields. For actual data fields then you want to convert the data to a fixed CHAR size.
For example - if the first field is 10 characters and you only have a length of 4 and it needs to be right-aligned:
Select concat(right(concat(space(10), 8888), 10), space(2), cast('AAA' As char(5)), cast('BBB' As char(8)), 'xxx');
For ease of maintenance - I would recommend documenting the code and structuring it:
Select concat(right(concat(space(10), 8888), 10) /* Field 1 position 01-10 - Account# */
, space(2) /* Field 2 position 11-12 - Filler */
, cast('AAA' As char(5)) /* Field 3 position 13-18 - Group */
, cast('BBB' As char(8)) /* Field 4 position 19-27 - SubGroup */
, 'xxx' /* Field 5 position 28-31 - End */
) /* end concat */
From ...
Where ...;
Believe it or not - CMS (cms.gov) requires files to be submitted as fixed-width flat files with a header record, detail records and a trailer record. There are others that also require fixed-width files for submission.
I had to create an SSIS project to load files sent by CMS - all of them were fixed-width flat files.
As a bit of a sidebar, stop using the TEXT datatype. It's been deprecated since 2005. Use VARCHAR(MAX) instead. Also, when you do, consider setting the "large object out of row" option for the table because the MAX datatypes default to "In-row" and will make a mess of your clustered index when short rows are present.