I have written a function to export the procedure definitions from my ASA 10 database. The idea was to create a seperate sql file for each of them so that we could add them to our source control system.

  declare view_defs no scroll cursor for select proc_name,proc_defn from sys.sysprocedure 
            where creator in (1,655) order by proc_name;
  declare err_notfound exception for sqlstate value '02000';

  open view_defs;
      export_defs: loop
        fetch next view_defs into @ls_name,@ls_def;
        if sqlstate = err_notfound then
          leave export_defs
        end if;

        SELECT DB_PROPERTY ( 'alias' ) into @ls_dbname;

        if @ls_dbname = 'vprod' then
            set @ls_dir = 'prod1\\';
        else
            set @ls_dir = 'test\\';
        end if;

        Set @ls_filename = '\\\\mycomp\\c$\\nsiapps\\db\\'||@ls_dir||@ls_name||'.sql';

        unload select proc_defn from sys.sysprocedure where proc_name = @ls_name to @ls_filename
            quotes off format ascii;

      end loop export_defs;
  close view_defs;

The problem that I have is I get \x0a for line feeds and everthing on one line. I have tried specifing rows delimited by \x0a and many other of the options listed for unload in the help text. Cant seem to come up with a combination that would give me the correctly formatted text. I can copy and paste them into the files one by one but that seems like a rather time consuming process. Any help would be appreciated.

asked 24 Jun '11, 17:20

trexco's gravatar image

trexco
336111423
accept rate: 0%

edited 24 Jun '11, 17:54

Graeme%20Perrow's gravatar image

Graeme Perrow
9.6k379124

Just something to add:

Of course the whole CR\LF problem is moot if you store your SQL scripts in the source control system before/while you build your database objects - then you don't have to extract them afterwards...

And as Breck has stated, if option PRESERVE_SOURCE_FORMAT is set (as default), the database will store your texts as is.

Yes, I'm aware that this is some kind of post-mortem advice:)

(27 Jun '11, 05:17) Volker Barth

Agreed on the moot aspect, however the database has never had anything stored in source control before. Seemed like a good idea to move it over there. I am a developer that has been 'elected' to be the dba, kind of learning on the fly here. We do full nightly backups and periodically I export and save the schema, but I thought moving things to source control would be a good idea. We use MS Source Safe currently, not ideal but what we have in house. The database is approx 26 gig. So once we get the scripts in source control we will edit them there in the future.

Thanks for the insights.

(27 Jun '11, 09:18) trexco

In addition to John's suggestion for ESCAPES OFF, you might want to use SYSPROCEDURE.source if formatting has been preserved; see the COALESCE() call in the example below.

Also, the cursor FETCH has already filled in @ls_def so the UNLOAD SELECT doesn't need to retrieve from SYSPROCEDURE again.

The following code has been slightly changed to work on my computer...

BEGIN
DECLARE @ls_name     VARCHAR ( 1000 );
DECLARE @ls_def      LONG VARCHAR;
DECLARE @ls_filename VARCHAR ( 1000 );

declare view_defs no scroll cursor for select proc_name,coalesce ( source, proc_defn ) from sys.sysprocedure 
            where USER_NAME ( creator ) = 'DBA' order by proc_name;
  declare err_notfound exception for sqlstate value '02000';

open view_defs;
      export_defs: loop
        fetch next view_defs into @ls_name,@ls_def;
        if sqlstate = err_notfound then
          leave export_defs
        end if;

Set @ls_filename = 'c:\\temp\\procs\\'||@ls_name||'.sql';

unload select @ls_def to @ls_filename
            escapes off quotes off format ascii;

end loop export_defs;
  close view_defs;

END;
permanent link

answered 25 Jun '11, 11:57

Breck%20Carter's gravatar image

Breck Carter
32.5k5417261050
accept rate: 20%

edited 25 Jun '11, 11:59

Brecks export code is excellent. I would like to point out that it is possible to add the codes for recreating the comments on procedure and functions. comments on procedure is remarks in sys.sysprocedure

so include that in the cursor and retrieve into @ls_remark. one could recreate the comment at the end of the procedure definition by replacing the unload statement with unload select @ls_def||'x0Dx0ACOMMENT on PROCEDURE DBA.' || @ls_name ||' is x27' || @ls_remarks || 'x27' to @ls_filename escapes off quotes off format ascii;

(14 Apr '12, 00:51) G_G
Replies hidden

sorry, some how the backward slash before x27 is missing in the above answer

(14 Apr '12, 17:51) G_G

BTW, I discovered the hard way on sql anywhere version 11.0.1.2506 that using declare for the remarks lead to truncation of long comment (only 548 bytes) despite the type being long varchar or varchar(2000)

I had to use instead create variable for @ls_remarks as long varchar to avoid the truncation problem

Caution, create variabe must be after all declare including cursor.

if used in stored procedure, one should drop the variable before ending the stored procedure

(14 Apr '12, 21:07) G_G

What OS are you using? (From the export path, I guess it's Windows.)

AFAIK, SQL Anywhere uses \x0A as the line delimiter. That's more appropriate on Unix than on Windows which usually uses \x0D\x0A.

When on Windows, I would try to open the exported scripts in Wordpad or other editors that can handle both kind of delimiters and check it the line breaks are displayed as wanted.

Alternatively, you might want to use the replace() function to change the contents - before writing to output file or in a further cycle to read the output/adapt it and write it back with the help of xp_readfile()/xp_writefile().

The following Q&A gives more hints...


EDIT: IMHO, even the "escapes off quotes off" option does not force SQL Anywhere to write a DOSish \x0D\x0A line break (CR\LF) as output - it still writes just a \x0A (LF).

To get the CR, too, for SQL Anywhere 9 you might want to replace this explicitly:

unload select replace(proc_defn, '\x0A', '\x0D\x0A')
from sys.sysprocedure where proc_name = @ls_name
to @ls_filename escapes off quotes off format ascii;

For SQL Anywhere 10 and above, you could use the sa_split_list() procedure to replace the newline with the result set row delimiter - which will always be appropriate for the according platform, as documented in the cited Q&A. The following uses this method and works with SQL Anywhere 11 and above:

unload select row_value
from (select proc_defn from sysprocedure where proc_name = @ls_name) SP
   outer apply sa_split_list (SP.proc_defn, '\n') 
to @ls_filename escapes off quotes off format ascii;
permanent link

answered 25 Jun '11, 05:30

Volker%20Barth's gravatar image

Volker Barth
40.1k361549819
accept rate: 34%

edited 27 Jun '11, 04:28

Try adding the ESCAPES OFF clause.

permanent link

answered 25 Jun '11, 07:04

John%20Smirnios's gravatar image

John Smirnios
11.9k396165
accept rate: 37%

Is this a one-off exercise or are you expecting to continually query your db for updated source?

I am tempted to wonder if your source control system is not being used to its full capacity, can't it query dbs and extract itself?

I have just run the Sybase Central Documentation Wizard and it perfectly formats the stored procedures in an html document(s). alternatively, this might meet your needs -

http://www.xsqlsoftware.com/LiteEdition.aspx

Cheers

Robin

permanent link

answered 27 Jun '11, 03:59

Uberseehandel's gravatar image

Uberseehandel
46113
accept rate: 0%

This was just to get the initial load into the source control system. Not sure what the capability is of MS Source Safe to query the database, but will investigate. Thanks for the thought.

(27 Jun '11, 09:24) trexco
Replies hidden

Don't try to investigate - Visual SourceSafe does not have the ability to query databases, not even MS ones.

But that's no disadvantage IMHO, just manage your SQL scripts like other text files. FWIW, starting with SQL Anywhere 10.0, Interactive SQL can integrate with SCC systems like Visual SourceSafe.

(27 Jun '11, 09:43) Volker Barth

Thanks for all of the ideas, I reformatted the query using the example that Breck supplied and all seems to be well with the exported files now. I did verify that preserve_source_format is on. Thanks again for all the various tips and responses, great to find this resource as I am sure I will have many questions in the future.

permanent link

answered 27 Jun '11, 09:28

trexco's gravatar image

trexco
336111423
accept rate: 0%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×48
×18

question asked: 24 Jun '11, 17:20

question was seen: 12,394 times

last updated: 14 Apr '12, 21:07