Skip to Main Content
  • Questions
  • How to verify that the correct version of PL/SQL software was deployed

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Jeff.

Asked: February 14, 2006 - 4:18 pm UTC

Last updated: December 05, 2006 - 9:43 pm UTC

Version: 9.2.0.4

Viewed 1000+ times

You Asked

In our company a separate group is responsible for deploying changes in our PL/SQL software to the production database. One of my responsibilities is to verify that this deployment was done correctly and I am looking for the best way to do this.

I am considering querying DBA_OBJECT_SIZE and comparing the value of the code_size column in the production database to the value in a test database that is known to have the correct version.

Is this the best approach, or do you have any suggestions or recommendations for another way of doing this.

Thanks!


and Tom said...

I'm not sure that would always work - slightly different parameters/features could result in different sizes.

I'd feel better with something like:

ops$tkyte@ORA9IR2> select name, sum(dbms_utility.get_hash_value(text,1,2000000)) hash from user_source group by name;

NAME HASH
------------------------------ ----------
CATCH_MEM_USED 19003528
CURRENT_CUSTOMERS 16237116
ORG_STRUCTURE_AI 4433926
ORG_STRUCTURE_AIFER 4370012
ORG_STRUCTURE_BI 5147190
P1 24360873
P2 24761297
PRINT_TABLE 107135500
RUNSTATS_PKG 102407647
STATE_PKG 31592143
TBL_ALIAS_AD 4593285
TBL_ALIAS_ADFEF 4607558
TBL_ALIAS_BD 4961320
TBL_ALIAS_BDFEF 5850923
TBL_HOST_AD 4971635
TBL_HOST_ADFEF 6250580
TBL_HOST_BD 5182707
TBL_HOST_BDFEF 7927818
TYPES 10938119

19 rows selected.


or in 10g:

ops$tkyte@ORA10GR2> select name, sum(ora_hash(text,2000000)) hash from user_source group by name;

NAME HASH
------------------------------ ----------
BD_ROW_C 13718684
AD_ROW_P 10299417
RUNSTATS_PKG 102275239
P2 24741989
MYSCALARTYPE 1795605
URLENCODE 22790690
BD_ROW_P 7067849
P1 24342767
DO_DDL 16894721
COLS_AS_ROWS 44758065
INSERT_XML_EMPS 16703206
COLS_AS_ROWS8I 30836386
MYTABLETYPE 1586939
P_P_C 10157338

14 rows selected.


Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Um.. Version Control Software

A reader, February 15, 2006 - 11:52 am UTC


Tom Kyte
February 15, 2006 - 12:04 pm UTC

umm, they want to make sure it was, umm, deployed.

sort of like checksumming a binary to ensure the code that was shipped, was actually, umm, deployed?

call it a santity check - someone is not trusting someone else to have done what they said they did.

version control software could tell us the software distribution was created.
it won't necessarily prove it was ever installed however.



In our case, we lable it.

NOTNA, February 15, 2006 - 12:09 pm UTC

In our codes we make it a practice that we sort of label the version on top of on the package, something like this:

CREATE OR REPLACE package calc_facl /* #B#05.13.3.014 */ as

by doing this, even if we wrap the package, we can verify that we have the correct version.

Tom Kyte
February 15, 2006 - 1:06 pm UTC

#bthat will definitely do it as well. (you had a pound sign B in there :)


Thanks for your input

Jeff, February 15, 2006 - 1:32 pm UTC

Tom,

Thanks for your time and input.

The only issue with your approach is that occasionally a deployer will run the script from an IDE tool that will reformat the SQL. Those changes will change the source code (capitalization, indenting etc.) and therefore the hash value, without changing the actual software that was deployed. That is why I was looking for a solution using something like the compiled size.

I like the labeling solution as it avoids the reformatting problem and the problems you noted with using the code_size. I will consider it as we work towards automating our deployment process.

Any other suggestions from the group would still be appreciated.



Tom Kyte
February 15, 2006 - 2:09 pm UTC

I would expect the same could be true of a source code formatting thing - especially if reformats sql and such (depending on release, we normalize most SQL now).

I would say if some deployer dared touched my code - they should be shot.

Perhaps you should deliver the code WRAPPED - so they cannot read it, touch it, play with it, modify it, anything it - short of INSTALL IT.

wrap it, those guys SHOULD NOT touch it.

Have you ever seen a formatter "do the wrong thing"? (rhetorical question). There is a bug I wouldn't want to have to try and track down.

Versioning

Kevin Shidler, February 15, 2006 - 3:23 pm UTC

I like the idea of placing a version # inside the code. Also, when the separate group installs the PL/SQL code in the database, give them a complete "packaged" zip file plus an executable to run to install the PL/SQL for you. All that group has to do is run the executable. I used to do this when deploying changes in dev, sit, uat, and prod. All that was ran was a Korn Shell script, which called everything else. Those set of scripts were moved through the dev, sit, uat, and prod through a source code control system.

After they are finished running your code, make sure your code logs all output, and tell them they must provide evidence that your code was installed. How? From the logfile that was generated via your scripts. I would also require them to retain those logs on a sharable, read-only share (perhaps Samba?) that can be accessed by your team for review after the implementation of your change.

You could also place in there a publicly callable function that returns a result in which this result determines your version of this code at some point in time. Wrap the code so the "algorithm" is not known.

Just a few suggestions...

Tom Kyte
February 15, 2006 - 9:49 pm UTC

wrap the code so no "person who thinks they are smarter than they are" touches the code.

My two cents. If someone was to even consider running code I delivered through some pretty printer - well, "click" would be my answer on the support phone line. That is "not smart"

If I may be so unbold

A reader, February 15, 2006 - 3:36 pm UTC

Sorry

Jeff, February 15, 2006 - 3:55 pm UTC

I did not realize that it was up to me to turn the bold off from the post before mine. The preview did not show that my test was all in bold.

Tom Kyte
February 15, 2006 - 9:49 pm UTC

no worries, it is "undocumented" :)

Include function to return version number

Warwick Sands, February 15, 2006 - 5:52 pm UTC

Hi all,
I agree totally with the idea of providing a 'release' for installation.

Having the release information as a comment is a nice idea, particularly for view definitions etc.

I also define a function within each package that returns the current version information including the compilation date. Depending on the site this is either a string or a PL/Sql table.

This allows a
dbms_output.put_line(package.version) ;
to be performed as required.

Thanks Tom for a great site.
This allows a

Wrapped code

Dodgy DBA, February 25, 2006 - 3:00 pm UTC

I agree - we always wrap the code that is being deployed and then no dodgy deployment staff can mess with it (and no dodgy DBAs can do any ad-hoc "tuning" either).

We've always automatically embedded a version number as a constant in our pl/sql when it's checked in. This constant could still be retrieved, even in wrapped code, by the functions we've written. Well at least it could in Oracle 7, 8 and 9 (doh!) - in 10g the wrapping is more severe (it looks more like uuencoded output) and the constants are no longer detectable. We'll have to come up with some other variant for 10g. One of the early posts in this thread had a version number in a comment on the "create or replace" line - we'll probably have a play with this, but I suspect this can still be altered by deployment staff. We may have to move to some sort of checksum method instead.

A word of warning, we've encountered code which compiles OK when unwrapped but won't compile once it's wrapped. The errors can usually be got rid of by tweaking the code (eg: adding table name aliases to columns in an ORDER BY is a common one). Also the wrap utility tends to be a bit behind the pl/sql compiler - some of the newer syntax (eg: in-line correlated column sub-selects) defeats it and the wrap utility just outputs the code unwrapped.

More worryingly we also found code that worked differently once it was wrapped. A TOO_MANY_ROWS exception correctly changed the value of a variable the code was SELECTing INTO in the wrapped code. In the unwrapped code it left the variable with its original value prior to the SELECT. This problem was in 9.2.0.5 but seems to be fixed in 10g. For this reason if you do decide to deploy wrapped code it should really be tested in its wrapped state. We leave the code unwrapped in our development system for convenience though.

Also its a shame wrap doesn't do triggers (or anonymous blocks) - but that's a good reason to keep code minimal in triggers and let them call wrapped stored procedures. Then the code is available for use outside of the triggers as well.







I only wish this was the worst of my problems.

Chuck Jolley, March 17, 2006 - 12:43 pm UTC

But, how do you prevent them from doing the compile the wrong direction? ;)

This has happend to me a couple of times. :o


Wrap view

Jayadevan, December 04, 2006 - 10:31 pm UTC

Dear Tom,
Can we wrap only procedures/functions/packages or we can wrap views and tables too?


Tom Kyte
December 05, 2006 - 9:43 pm UTC

just code.

all sql will always be visible - even sql wrapped in plsql.

wrapping a table doesn't even begin to make sense to me.

More to Explore

DBMS_UTILITY

More on PL/SQL routine DBMS_UTILITY here