Author Archives

Podcast from OOW 2008

Stirring Up Controversy

 

…Tom Kyte sits down with Oracle Magazine editor Tom Haunert at Oracle OpenWorld 2008 and stirs things up in this conversation about Oracle OpenWorld happenings, a new approach to publishing, and the trouble with triggers. …

A new book on APEX coming out…

There is a new APEX book coming out soon - I wrote a foreword for it.  There has been some discussion of it on asktom - and I thought I’d publish the foreword here:

I consider myself a pragmatic person – one that uses the right tools for a job, one that employs the most straightforward and easy way to accomplish a task.  To that end, I’ve been a great supporter and fan of Oracle’s Application Express (APEX) from before the day it was introduced.  I say “before the day” because I’ve had the honor and pleasure of using APEX long before it was released to the public at large – my website, http://asktom.oracle.com/, is one of the first websites ever built with the software that was to become known as APEX.

APEX is one of the most pragmatic database development tools I know of.  It does one thing and one thing well – it rapidly implements fully functional database applications – applications that are used to predominantly access, display and modify information stored in the database (you know, the important applications out there).  It facilitates using the database and it’s feature set to the fullest – allowing you to implement some rather complex applications, with as little work (code) as possible.  It is possible to build extremely scalable applications with a huge user base (http://metalink.oracle.com/ for example is built with APEX).  It is possible to build extremely functional applications, with seriously powerful user interfaces (APEX itself is written in APEX, proof of this).  It is easy to build applications rapidly, the current version of http://asktom.oracle.com was developed in a matter of days by two developers – in their spare time, it was not a full time job.

While it all sounds wonderful and easy so far, APEX is a rather sophisticated tool with many bits of functionality and a large degree of control over how the generated application will look and feel.  To fully utilize the power of APEX – one needs to have a guide, a mentor show them how to do so; very much akin to what I do with people regarding the Oracle database.

This book – Oracle Application Express – is that guide, the authors – Scott Spendolini and John Scott – are those mentors.  The book walks you through the steps you need to understand after you’ve installed and started using APEX, to go beyond the sample applications.  Covering diverse topics such as “Using the database features to full advantage” (one of my favorite topics) to “SQL Injection Attacks” – what they are and how to avoid them in APEX – to “Printing”; you’ll find many real world issues you will be faced with explained, demystified and solved in this book.

For example, Chapter 5 “Data Security” covers a wide breadth of topics regarding securing your database application.  There is a section on URL injection issues – what they are, how they are exploited, why you care about them and finally how to protect yourself from them.  There is a section on Session State Protection – following the same format –what it is, how it is exploited, why you care and finally how to protect yourself.  The same mentoring occurs with data level access where the authors introduce how to use Virtual Private Database, a core database feature – not really an APEX feature, to protect your data from unauthorized access.  Lastly, a critical application feature – Auditing – is discussed in depth using the “what it is, why it is, why you care and then how to do it” approach.  Whilst some of the content in this chapter is not specific to APEX, it is needed to give you a holistic view to building database applications – which is what this book is about.

This book covers not just the nitty gritty details of building a secure application, it covers all you need to build database applications with APEX.  When they are done with security, the authors move onto other necessary topics such as how to perform screen layout and application screen navigation, how to integrate reports and charts, how to integrate web services – enabling you to perform application integration – in an APEX environment, and much more.

If you are an APEX developer just starting out, or an APEX developer with experience under their belt but want to learn more about the environment you are using – this book is for you.  It describes from start to finish how to build a secure, functional, scalable application using the APEX application development environment.

Thomas Kyte
http://asktom.oracle.com/

Interesting thought…

I read this yesterday…

Got me thinking about Q&A sites…

I believe the author there has something - if you introduce a barrier to entry, it will have it so that only those that really want in - are in.  I don’t know that metafilter is better/worse/same as reddit and digg - I do know that I used to follow digg, then it became a “not as good place” for me.  I follow reddit - but it is becoming very much the same.  I’ve never used metafilter (on my todo list now) so cannot compare it.  But the *idea* proposed, the concept - it does seem to have merit.

It would be neat to know if this has ever been studied before - does anyone know?  Thoughts?

 

ps: I’m not thinking about doing this in asktom.  I was asking in general for “social sites” like digg, reddit and the like.  Sites that start off nicely with a small focused community but then turn into a bit mess when they become ‘cool’.

Read this…

I read a lot of "stuff".  Yeah, I know, I’m writing less here - but that leaves more time to read over there…

I read lots of blogs, lots of forums.  I lurk.  I observe.  I see what people are saying.

 

I liked what Cary Millsap just said:

I don’t mean “show and tell,” where someone claims he has improved performance at hundreds of customer sites by hundreds of percentage points [sic], so therefore he’s an expert. I mean show your work, which means documenting a relevant baseline measurement, conducting a controlled experiment, documenting a second relevant measurement, and then showing your results openly and transparently so that your reader can follow along and even reproduce your test if he wants to.

Check out the entire posting - and the book he is talking about.  Also, check out his new venture.  A pretty good read…

I don’t know…

I don’t know if

a) I’m getting grumpier as I get older

b) people are losing the ability to phrase a question. 

It just seems to me that day by day, the quality of the questions goes down.  I don’t remember people asking questions like this just 8 years ago.  I’ve been participating in forums since 1994.  "Back in the day", the questions were mostly thought out, with examples - with some background, with some thought.  In the last couple of years - this seems to be changing - universally.

Oh well, it is probably related to both bullet points… Anyway here is the QOD - question of the day.

Subject: query is not using particular partition and index despite use full table scan

Entire question:

SELECT count(*)
FROM
DIM_BANK RIGHT OUTER JOIN FACT_JRNL_ACTG ON (DIM_BANK.BANK_ID=FACT_JRNL_ACTG.BANK_ID)
LEFT OUTER JOIN DIM_BSA ON (FACT_JRNL_ACTG.BSA_ID=DIM_BSA.BSA_ID)
LEFT OUTER JOIN DIM_FY ON (FACT_JRNL_ACTG.FY_ID=DIM_FY.FY_ID)
LEFT OUTER JOIN DIM_APD ON (FACT_JRNL_ACTG.APD_ID=DIM_APD.APD_ID)
LEFT OUTER JOIN DIM_PSCD ON (FACT_JRNL_ACTG.PSCD_ID = DIM_PSCD.PSCD_ID)
WHERE
(
(DIM_BANK.BANK_ACCT_CD IN (’33′)
OR ‘*’ IN (’33′))
AND DIM_PSCD.PSCD_CLOS_CL_CD IN (’1′, ‘4′, ‘5′)
AND CASE DIM_BSA.CASH_ACCT_FL WHEN 0 THEN ‘No’ WHEN 1 THEN ‘Yes’ END = ‘Yes’
AND DIM_APD.PER != 0
AND DIM_APD.PER != 99
AND DIM_APD.FY < 2008
OR DIM_FY.FY = 2008
AND DIM_APD.PER <= 6
AND DIM_APD.PER != 0
AND CASE DIM_BSA.CASH_ACCT_FL WHEN 0 THEN ‘No’ WHEN 1 THEN ‘Yes’ END = ‘Yes’
AND DIM_PSCD.PSCD_CLOS_CL_CD IN (’1′, ‘4′, ‘5′)
AND (DIM_BANK.BANK_ACCT_CD IN (’33′)
OR ‘*’ IN (’33′))
);

 

That’s it folks.  "My query isn’t doing partition elimination (probably, I’m sort of GUESSING) and isn’t using some index (on some column of some table)"

Before anyone says anything - this comes from the US.

Some wows from reading the query:

  • "(DIM_BANK.BANK_ACCT_CD IN (’33′) OR ‘*’ IN (’33′)) - why would you do that?
  • "CASE DIM_BSA.CASH_ACCT_FL WHEN 0 THEN ‘No’ WHEN 1 THEN ‘Yes’ END = ‘Yes’" - why would you do THAT?
  • "CASE DIM_BSA.CASH_ACCT_FL WHEN 0 THEN ‘No’ WHEN 1 THEN ‘Yes’ END = ‘Yes’" - just in case you didn’t believe us the first time
  • wow, more duplicated predicates…
  • outer joins to DIM_BSA, but we have that neat predicate using CASE - if we actually needed to outer join to DIM_BSA then all of the attributes would be NULL - the predicate would never be true - hence, we do not need or want to outer join to DIM_BSA
  • Same comment about DIM_FY, we outer join to DIM_FY, but if we make up a row - then DIM_FY’s attributes will all be null and DIM_FY.FY = 2008 cannot be true (or false, it is unknown)
  • Ditto for DIM_APD
  • and of course DIM_PSCD
  • and just to make it 100% complete, the outer join to DIM_BANK - ditto. every single outer join in this query, should not be there.

I’ve responded with:

My car won’t start.  Now we are even, we have shared the same level of detail regarding our respective problems.

when others then null, redux

It keeps happening.

Over and over it keeps happening.

Here is case 124,215,412,523 for your review.

The user writes me:

… I have a situation where I have started receiving the ‘Cursor is Closed’ SQLException from a stored procedure, say, SP_A, suddenly for last 5-6 weeks, since 2nd week of March. This happens only intermittently. If I take the same parameters and execute the sp again after a few minutes after getting the error, it does not generate the error and returns expected results back.

Additional details as requested:

what ora-xxxx error are you getting

Unfortunately, it does not generate an ORA-???? error. I know that many a times, the ‘Cursor is Closed’ error is a coding issue, but in this case, that is not the case. I cannot create this error at will, I have not been able to create the error in our development or user acceptance environment. Even in production, I cannot recreate it with same parameters that have generated the error.

The reason I think this could be oracle memory issue is that we very recently moved from 9i to 10g RAC. This application - java code and stored procedures - have been working for about 5 to 6 years now. Even the errors of Cursor is closed we receive are not consistent i.e. The parameters that generate the error now will work with exact same code a few minutes later.

Ok, here they are - they say "there is no ora-xxxx error, Oracle is just closing cursors on us - no fair.  We know this cannot be a bug in our code, this is a bug in Oracle. 

The story ALWAYS goes that way.  I just finally gave up… closed the question.  They followed up:

 

What was found that SP_A had exception clause of WHEN OTHERS that was masking the actual error.
When we removed that error, this is the error we see

ORA-04068: existing state of packages has been discarded
ORA-04065: not executed, altered or dropped stored procedure "SP_A"
ORA-06508: PL/SQL: could not find program unit being called: "SP_A"
ORA-06512: at "SP_B", line 317
ORA-06512: at line 1

This is what has been happening intermittently ( we just did not know, because the way the sp was
coded and the java code interacted with returned parameters, it manifested into Cursor Closed Error
).

 

and now they want "insight" into why this is happening….

 

Remember everyone, everyone remember, keep in mind:

When others not followed by RAISE or RAISE_APPLICATION_ERROR is almost certainly, with 99.999999999% degree of accuracy, a bug in your developed code.  Just say "no" to when others not followed by raise or raise_application_error!

http://www.oracle.com/technology/oramag/oracle/07-jul/o47asktom.html

Seems like a good idea…

Check it out - and comment away…  Tyler has a good idea/thought going on over there.

Also (total context switch here) this is the coolest new bit of SQL I’ve had the pleasure of writing for a while (11g and above only…)

 

ops$tkyte%ORA11GR1> with data  2  as  3  ( select when, thing, val  4      from t2  5    unpivot ( val for thing in  6              ( LF_ROWS, LF_BLKS, LF_ROWS_LEN, LF_BLK_LEN,  7                BR_ROWS, BR_BLKS, BR_ROWS_LEN, BR_BLK_LEN,  8                DEL_LF_ROWS, DEL_LF_ROWS_LEN, DISTINCT_KEYS,  9                MOST_REPEATED_KEY, BTREE_SPACE, USED_SPACE, 10                PCT_USED, ROWS_PER_KEY, BLKS_GETS_PER_ACCESS, 11                PRE_ROWS, PRE_ROWS_LEN, OPT_CMPR_COUNT, OPT_CMPR_PCTSAVE ) 12            ) 13  ) 14  select THING, before, middle, coalesce, rebuild, rebuild-coalesce diff 15    from data 16   pivot( max(val) for when in ( 'before' as before, 'middle' as middle, 17                                 'coales' as coalesce, 'rebuil' as rebuild ) 18        ) 19   order by thing 20  /

THING                    BEFORE     MIDDLE   COALESCE    REBUILD       DIFF-------------------- ---------- ---------- ---------- ---------- ----------BLKS_GETS_PER_ACCESS          4          4          4          4          0BR_BLKS                       6          6          6          4         -2BR_BLK_LEN                 8028       8028       8028       8028          0BR_ROWS                    2810       2810       1409       1405         -4BR_ROWS_LEN               33639      33639      16856      16809        -47BTREE_SPACE            22524924   22524924   11322528   11274488     -48040DEL_LF_ROWS                   0     238415          0          0          0DEL_LF_ROWS_LEN               0    9601917          0          0          0DISTINCT_KEYS            499999     488415     250000     250000          0LF_BLKS                    2811       2811       1410       1406         -4LF_BLK_LEN                 7996       7996       7996       7996          0LF_ROWS                  499999     488415     250000     250000          0LF_ROWS_LEN            20121735   19665121   10063204   10063204          0MOST_REPEATED_KEY             1          1          1          1          0OPT_CMPR_COUNT                0          0          0          0          0OPT_CMPR_PCTSAVE              0          0          0          0          0PCT_USED                     90         88         90         90          0PRE_ROWS                      0          0          0          0          0PRE_ROWS_LEN                  0          0          0          0          0ROWS_PER_KEY                  1          1          1          1          0USED_SPACE             20155374   19698760   10080060   10080013        -47

21 rows selected.

I used pivot to turn my rows into columns and then unpivot to turn some of my columns into rows (I flipped this result side on its side!)

A bit of background, I wanted to compare the effects of:

  • freshly built index (before)
  • to an index that had lots of deletes done to it (middle)
  • to an index that was just coalesced after those deletes (coalesce)
  • to a rebuilt index (rebuild)

So, in order to capture the information I just did this:

ops$tkyte%ORA11GR1> create index t_idx on t(x,object_name);ops$tkyte%ORA11GR1> analyze index t_idx validate structure;

ops$tkyte%ORA11GR1> create table t2  2  as  3  select 'before' when, index_stats.* from index_stats;

delete data here....

ops$tkyte%ORA11GR1> analyze index t_idx validate structure;ops$tkyte%ORA11GR1> insert into t2  2  select 'middle' when, index_stats.* from index_stats;

ops$tkyte%ORA11GR1> alter index t_idx coalesce;ops$tkyte%ORA11GR1> analyze index t_idx validate structure;ops$tkyte%ORA11GR1> insert into t2  2  select 'coales' when, index_stats.* from index_stats;

ops$tkyte%ORA11GR1> alter index t_idx rebuild;ops$tkyte%ORA11GR1> analyze index t_idx validate structure;ops$tkyte%ORA11GR1> insert into t2  2  select 'rebuil' when, index_stats.* from index_stats;

Now, index_stats has lots of columns… and my table T2 has very few rows - so, if I turn my rows into columns and columns into rows, I’d be able to better visualize this particular set of data on screen (in sqlplus of course…)

That is what that pivot/unpivot query did for me - I like it…

 

Looks better than this did :)

 

ops$tkyte%ORA11GR1> select * from t2;

WHEN       HEIGHT     BLOCKS NAME------ ---------- ---------- ------------------------------PARTITION_NAME                    LF_ROWS    LF_BLKS LF_ROWS_LEN LF_BLK_LEN------------------------------ ---------- ---------- ----------- ----------   BR_ROWS    BR_BLKS BR_ROWS_LEN BR_BLK_LEN DEL_LF_ROWS DEL_LF_ROWS_LEN---------- ---------- ----------- ---------- ----------- ---------------DISTINCT_KEYS MOST_REPEATED_KEY BTREE_SPACE USED_SPACE   PCT_USED ROWS_PER_KEY------------- ----------------- ----------- ---------- ---------- ------------BLKS_GETS_PER_ACCESS   PRE_ROWS PRE_ROWS_LEN OPT_CMPR_COUNT OPT_CMPR_PCTSAVE-------------------- ---------- ------------ -------------- ----------------before          3       2944 T_IDX                                   499999       2811    20121735       7996      2810          6       33639       8028           0               0       499999                 1    22524924   20155374         90            1                   4          0            0              0                0

middle          3       2944 T_IDX                                   488415       2811    19665121       7996      2810          6       33639       8028      238415         9601917       488415                 1    22524924   19698760         88            1                   4          0            0              0                0

coales          3       2944 T_IDX                                   250000       1410    10063204       7996      1409          6       16856       8028           0               0       250000                 1    11322528   10080060         90            1                   4          0            0              0                0

rebuil          3       1536 T_IDX                                   250000       1406    10063204       7996      1405          4       16809       8028           0               0       250000                 1    11274488   10080013         90            1                   4          0            0              0                0

Hear, Hear

Double, double

 

Been a while since I’ve pointed to his blog - but this one is one that resonated with me.

I related to it for this reason:  when people describe what problems they are facing in technology - they very often assume the person they are describing it to have the same background, nomenclature, experiences.  What they forget is we don’t work with them, we don’t share the same jargon and most importantly - we haven’t been staring at the problem like they have for the last 5 days - it is all new to us.  And therefore, we need lots of detail. 

For me, this manifests itself in a question like this: I have this/these table(s).  I need a report that looks like this: …. This query is failing.  Please correct it.

It won’t matter how loud or long they say "Please correct it", it won’t happen - we don’t know what the question is yet!

Double, double - indeed.

Another ‘question of the day’…

This time, the question is not because it was poorly phrased.  It is because it is regarding an area I want to bring to the attention of a larger audience.

The question went like this:

 

<quote>

Suppose, I have a table having country currency combinations with a primary currency. The below is a sample data.

Country        Currency    Primary_CurrencyUS             USD         YUS             USN         NUS             USS         N

And, I have a before update trigger on the above table for each row

(using autonomous transaction to avoid mutating error) to check whether

the country has any primary currency. I am giving the below update.

</quote>

Ok, serious red flags here - They have a business rule apparently that AT MOST one currency can be "primary" for a given country - that is - COUNTRY must be UNIQUE when PRIMARY_CURRENCY=’Y’ (what I call selective uniqueness).  Now, I might suggest we are missing an entity in this model - that is, the primary currency ‘flag’ should not be there, but rather there should be two entities - primary_currency, and other_currencies - perhaps.  Then, the problem is simple - COUNTRY would be the primary key of the primary_currency table - and COUNTRY,CURRENCY would be the primary key of the other - an in fact, if the rule was "A country may have at most one primary currency and must have at least one primary currency" - then enforcing that more complex one would be trivial - just add a foreign key from other_currencies to primary_currency - and you are done.  Could not be easier. 

But - back to the red flags:

  • I have a before update trigger:  I have written many times that you cannot enforce integrity constraints that cross objects (tables) in the database (like referential integrity does), nor constraints that cross rows in a single table (like uniqueness does) without using the LOCK TABLE command.  Since reads are not blocked by writes - and you cannot see others uncommitted work - you need to serialize access.
  • Using autonomous_transaction:  These are almost universally "misapplied".  They have one use - in a "LOG_ERRORS" routine, called from a WHEN OTHERS exception handler (which would of course be followed by RAISE;)
  • Using autonomous_transaction to avoid mutating error:  Ok, now I know we are in serious trouble here.  If you have to use an autonomous transaction to avoid a mutating table constraint (not error, a constraint, a subtle warning to the developer "what you are trying to do is something you should not be doing") - you have a bug in your code, I’m 99.999999% certain of that - I would be very hard pressed to come up with a valid reason in real life to use an autonomous transaction to avoid a mutating table constraint.

So, we have these HUGE red flags - all of which get proven out in the next bit - everything I guessed:

  • This does not work in single user scenarios
  • This does not work in multi user scenarios
  • In short, this does not work - it is a huge bug

Are shown true:

Update Country_Currency_Refset is_primary_currency = 'Y'where (country_code = 'US' and currency_code = 'USN');

And the trigger is working fine and giving the correct message that it cannot be updated as there

is already one primary currency against that country Now I update the data as below

(No primary currency)

Country        Currency    Primary_CurrencyUS             USD         NUS             USN         NUS             USS         N

and try to update the data with the below condition

Update Country_Currency_Refset is_primary_currency = 'Y'where (country_code = 'US' and currency_code <> 'USD');

In this case, the trigger is failing and updating other two records. Why is this behaviour?

And how can we over come the same?

Sorry, the trigger is not failing, the trigger is just doing precisely what it was coded to do.  The problem is the person coding the trigger doesn’t understand transactions and concurrency controls and how the database works.  By using the autonomous transaction to query the table - it is as if they started a brand new session to query that table.  Of course that brand new session cannot see any changes made by not yet committed!  Including the changes the trigger is trying to validate.  This is PRECISELY why we have a mutating table constraint - your row level trigger is being fired as the rows are modified - if you were able to query the table in the trigger without the autonomous transaction - you would see the table half updated (and then what, what a MESS that would be).  So, since Oracle is evil and prevents you from doing something bad here - you use an autonomous transaction - you get a consistent view of the table to be sure, but you cannot see the data you are trying to validate!!!  That makes validation pretty hard.

Even if you did the "common mutating table constraint workaround" - by deferring your reads until the AFTER (not for each row) trigger, you cannot do this check in a trigger without LOCKING THE TABLE.  You would have to serialize access in order to prevent two concurrent sessions from each creating a primary currency record at the same time. 

I would prefer a two table solution here:

ops$tkyte%ORA11GR1> create table primary_currency  2  ( country  varchar2(2) primary key,  3    currency varchar2(3)  4  )  5  organization index  6  /

Table created.

ops$tkyte%ORA11GR1> create table other_currencies  2  ( country  varchar2(2),  3    currency varchar2(3),  4    constraint other_currencies_pk  5       primary key(country,currency),  6    constraint must_have_at_least_one_primary  7       foreign key(country)  8       references primary_currency(country)  9  ) 10  organization index 11  /

Table created.

That solves the problem quite elegantly - and even enforces the complex "must have a primary currency" constraint if you implement the foreign key.  However, if they were to keep this single table, then I would say:

drop your trigger.

and promise to never use autonomous transactions to avoid mutating table constraints (I said "mutating table CONSTRAINTS", not error - the error is you using an autonomous transaction to destroy your data integrity) ever again.

add:

create unique index only_one_can_be_primary on country_currency_ref

( case when is_primary_currency = ‘Y’ then country_code end );

 

I hate triggers

I hate autonomous transactions

I hate when others

If we removed those three things from PLSQL - we would solve 90% of all application bugs I think… No kidding.  I know, in the right hands, they are powerful tools.  However, they fall into the wrong hands far too often.

The Question of the day…

Some days… Some days the questions just make me scratch my head….


ROW TO COLUMN CONVERSION   April 30, 2008 - 5am US/Eastern 

Reviewer: ROOPA from india 



HOW TO CONVERT YEARLY DATA INTO MONTHLY DATA? 



Followup   April 30, 2008 - 10am US/Eastern: 

BY MAKING IT UP I GUESS? 

Could it be more ambiguous?  I have yearly data (one presumes that is data aggregated to the level of a year).  How do I convert that into monthly data.  Short of "making it up", I have no idea… do you?

Now, they did followup later with

 

table1 formatMONTH                  AMOUNT_PAID01.12.2006 00:00:00        539501.11.2006 00:00:00         56701.11.2006 00:00:00        197401.04.2007 00:00:00        246201.04.2007 00:00:00        197401.11.2006 00:00:00        539501.02.2008 00:00:00        5395   

table2 formatMONTH         JAN  FEB MAR APR MAY JUN JUL AUG SEP OCT  NOV  DEC01-DEC-2006   0    0   0   0   0   0   0   0   0   0    0   539501-FEB-2007   0   5395 0   0   0   0   0   0   0   0    0    001-NOV-2006   0    0   0   0   0   0   0   0   0   0   5395  0

how to convert table1 format into table2 format i.e yearly data to monthly data.

 

Now, I don’t know about you - but table1 looks suspiciously like "discrete observations with an associated date - the date consisting of year, month and day".  I certainly do not see "yearly data".

I also like how they used 5,395 three times, just to make it as ambiguous as possible (wonder what happened to 567, 1,974 and so on?)  They skipped what are likely the interesting output examples - their "yearly data that is not yearly" that has more than one observation in a month.

I guess, I GUESS, their date format is DAY-MONTH-YEAR now, that changes table1 to look suspiciously like "discrete observations with an associate date - the date consisting solely of year and month".  But, we’d be GUESSSING.

And I see a 01-FEB-2007 in table2, but I see 01.02.2008 in table1.  I have to presume that is a "typo"

sigh, and there wasn’t even a create table, insert into table supplied - they want me to do that.

And the output looks utterly useless.  If column 1 is "01-dec-2006", why bother having a DEC column in the output?  We already KNOW what month this is for - every row will have 11 zeros, every single one.  Seems a bit "silly".

Asking good, well formed questions is not an art, not magic.  It is however a skill.  And I find many times that when I frame my question for someone else - I find my answer.

Goes back to yesterdays post.  Writing software requires some things - a plan being one of them.  Until you can phrase your requirements in a detailed fashion - I’m not sure you know what they are or why you are doing something…..

 

We have a runner up for second place..

entire question is:

Record level Audit Old\New value same Error  April 30, 2008 - 9am US/Eastern

Reviewer:  sasirekha  from India

I have some problem using Audit Record.

Generally if we map a record to the audit Record, it will track the details of

the table insert, update, delete.

While I update the record, it will insert two different row in audit record

like  Audit Action K and N.

But both are contain the same values..

I need the old and new value.

Can any one please give me the solution with this !

questions from me:

  • what is an "audit record", must be well defined - they are using it
  • "if we map a record to the audit record" - not really sure what that means
  • "like audit action K and N" - K and N?? huh?
  • "but both are contain the same values - I need the old and new value" - well, why didn’t they access the old and new values?
  • where is the sample, the example, the thing that shows us what you are really doing….

And in a close 3rd place…

How to speed up the insert and update in a partion table of more than 60 millions Rows ?

Best regards,

Sam.

I don’t get it some days, just do not get it.