T-SQL Question

  • I have to write a query that will output a ---fixed lenght -- sequential text file? for example I have 100 records (100 rows) and the way client needs it is all those records in a single row.

    record1|record2|record3|til end ...

    Any help would be appreciated..

    Thank you..

  • Hopefully this will give you some ideas.

    declare @Tmp table

    (test1 varchar(5))

    insert into @Tmp

    select '1234'

    union

    select '4321'

    union

    select 'abcd'

    union

    select 'dcba'

    Declare @teststrng varchar(100)

    set @teststrng=''

    select @teststrng=@teststrng + test1 + '|' from @Tmp

    select @teststrng

    Dan

    If only I could snap my figures and have all the correct indexes apear and the buffer clean and.... Start day dream here.

  • maynor_ramirez (8/9/2011)


    I have to write a query that will output a ---fixed lenght -- sequential text file? for example I have 100 records (100 rows) and the way client needs it is all those records in a single row.

    record1|record2|record3|til end ...

    Any help would be appreciated..

    Thank you..

    I have a couple questions.

    Did the client give you a layout that includes how they want the fields justified?

    When the field within the row/record line is not the total length of the field do you need to fill the unused characters with spaces, leading or ending 0's if numeric?

    Fixed length means that each row within the set you are sending must be so many characters.

    field1 = alpha-Numeric length 5

    field2 = numeric length 10

    field3 = character length 3

    field4 = character length 8

    field5 = character length 1

    results could be different depending on the client see below

    abcd12|0000001009|ABC|_______r|0

    abcd12|______1009|ABC|r_______|0

    abcd12|1009______|ABC|_______r|0

    Please look at the specs and post what they are. I had to use _ 's in my example since the spaces were removed when I did a preview of the post.

  • Yes,

    The total size is 46 characters, divided by

    1-17 acct # right justified,

    18-27 left justified, 0 filled,

    etc..etc,to 46 , I have managed that piece -

    SELECT

    LEFT(CAST(CAST('123456789' as int) as varchar(9))+ REPLICATE(' ',17),17)+

    RIGHT(REPLICATE('0',10) + CAST(CAST('123456' as int) as varchar(10)),10)+'0'+'0'+

    CAST(CAST('070511' as int) as varchar(6))+

    RIGHT(REPLICATE('0',12) + CAST(CAST('27807' as int) as varchar(12)),12)+'0'

    FROM db..table1

    but I do not know how cannot start the next record in the same row, which in this case it will have to start on position 47. the record count is 2,893 records.

    Thanks

  • write the records as a string and add them to a variable as I did in my example this will cause the ouput of the variable to output one long line.

    Dan

    If only I could snap my figures and have all the correct indexes apear and the buffer clean and.... Start day dream here.

  • Somethings along those ling could do it too... just to have 2 options.

    SELECT

    T.name,

    STUFF((

    SELECT

    ',' + name

    FROM

    sys.columns C

    WHERE C.object_id = T.object_id

    ORDER BY

    name

    FOR

    XML PATH('')

    ) , 1 , 1 , '') As Columns_

    FROM sys.tables T

    ORDER BY name

  • When I used to do extracts for third party clients that needed this format we usually used a char(13) return to start the next record in the txt file.

  • Would you please provide an example - for the variable?

    Thanks

  • using the select statement you listed and changing it a bit. try this. Since I can only see an example of one record and not the table definition makes this a bit difficult.

    I ran this to return as text in the query window. you probably can remove the +char(13) and get the same results I did replace your ' ' with an underscore so the spaces would not be trimmed here. I also added the | between the fields

    /*------------------------

    SELECT

    LEFT(CAST(CAST('123456789' as int) as varchar(17))+ REPLICATE('_',17),17)+ '|' +

    RIGHT(REPLICATE('0',10) + CAST(CAST('123456' as int) as varchar(10)),10)+ '|' + '0' + '|' +'0'+ '|' +

    CAST(CAST('070511' as int) as varchar(6))+ RIGHT(REPLICATE('0',12) + '|' +

    CAST(CAST('27807' as int) as varchar(12)),12) + '|' +'0' + char(13)

    union

    SELECT

    LEFT(CAST(CAST('3456789' as int) as varchar(17))+ REPLICATE('_',17),17)+ '|' +

    RIGHT(REPLICATE('0',10) + CAST(CAST('123456' as int) as varchar(10)),10)+ '|' + '0' + '|' +'0'+ '|' +

    CAST(CAST('070511' as int) as varchar(6))+ RIGHT(REPLICATE('0',12) + '|' +

    CAST(CAST('27807' as int) as varchar(12)),12) + '|' +'0' + char(13)

    union

    SELECT

    LEFT(CAST(CAST('1234569' as int) as varchar(17))+ REPLICATE('_',17),17)+ '|' +

    RIGHT(REPLICATE('0',10) + CAST(CAST('123456' as int) as varchar(10)),10)+ '|' + '0' + '|' +'0'+ '|' +

    CAST(CAST('070511' as int) as varchar(6))+ RIGHT(REPLICATE('0',12) + '|' +

    CAST(CAST('27807' as int) as varchar(12)),12) + '|' +'0' + char(13)

    ------------------------*/

    ------------------------------------------------------

    123456789________|0000123456|0|0|70511000000|27807|0

    1234569__________|0000123456|0|0|70511000000|27807|0

    3456789__________|0000123456|0|0|70511000000|27807|0

    (3 row(s) affected)

  • I've read from your request that you want one long string returned for the entire file: i.e. each row is stored in 47 characters with no row separator in between. Apart from the fact that this may result in a very long line with which most editors will have problems, MS SQL Management Studio has issues with columns with long texts in it. Your query will return a single row with a single column in it. By default SSMS truncates each column at 256 characters and the longest string it can return per column is 64K characters. In other words, you will probably not be able to show the entire length of your column in SSMS. If you have some other program that will execute the statement and write the result to a file, you might be able to do it though.

    Anyway here is a statement that will generate a fixed length string per row, then concatenate each row into one long string, with no row separators.

    Please note that if any of the columns can contain null's, you will have to use f.e. isnull() to provide an alternative value for that column if it contains null, or the entire row with a null value in one of it's columns will disappear from your output.

    declare @table1 table (

    acct int not null,

    col1 varchar(12) not null,

    col2 datetime null,

    primary key (acct)

    );

    insert @table1(acct, col1, col2)

    select 1, 'nr 1', {d '2011-01-01'}

    union all select 675876, 'nr 2', null

    union all select 123456789, '123456', getdate();

    declare @result varchar(max);

    select @result = (

    SELECT right(replicate(' ', 17) + convert(varchar(17), t1.acct), 17)

    + '|' + left(convert(varchar(9), t1.col1) + replicate('0',9), 9)

    + '|' + left(isnull(convert(varchar(10), t1.col2, 121), '') + replicate(' ', 10), 10) as [text()]

    -- + up to 47 characters

    from @Table1 t1

    for xml path(''), type

    ).value('.', 'varchar(max)');

    select datalength(@result), @result;



    Posting Data Etiquette - Jeff Moden[/url]
    Posting Performance Based Questions - Gail Shaw[/url]
    Hidden RBAR - Jeff Moden[/url]
    Cross Tabs and Pivots - Jeff Moden[/url]
    Catch-all queries - Gail Shaw[/url]


    If you don't have time to do it right, when will you have time to do it over?

  • I bet that you have misuderstood the client requirements.

    Or misrepresented them in your post:

    Most likely they want standard fixed-length extract, which means that every field will be of the fixed length:

    FIELD1FIELD2FIELD3

    FIELD1FIELD2FIELD3

    where each field is always of the same size in every row, hence no field separator in required.

    However if your client really wants something like this:

    FIELD1FIELD2FIELD3|FIELD1FIELD2FIELD3

    Then I would still advice output results into file in the standard format and then replace all NewLine chars with whatever you want eg. bar. You can do it using dos command, vb or Java script or using PowerShell.

    Sorry mate, but concatinating all of extracted data into one string in T-SQL is plainly stupid.:w00t:

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thank you guys...

  • No need to fuss with all that. Just do a BCP out to the file with no row terminator. 😉

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.
    "Change is inevitable... change for the better is not".

    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)
    Intro to Tally Tables and Functions

Viewing 13 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic. Login to reply