Category Archives: Programming

Upcoming WordPress Plugin Releases

Quite regularly I attempt to do something in WordPress, which I can’t find a simple way to achieve through the use of the Templating Tags. When this happens, I usually whip up a very simple plugin – which in most cases is just a simple function I can then reuse somewhere else.

In the coming days, I’ll be releasing some of the plugins I’ve written. A few of them had previously been written, however I reinvented the wheel so I could gain an understanding of how the WordPress works on the inside.

Currently slated for release:

The plugins should be considered in beta, as I spent as little time on them as required to get the job done. That being said, they are enabed and have been running here error free for quite some time.

Oracle DECODE Function

The Oracle DECODE function provides similar functionality to an IF-THEN-ELSE statement. The general format for an Oracle DECODE function is:

DECODE(expression, value1, result1 [, valuen, resultn], [default])

In the above example, expression represents what you want to evaluate. The valueX fields represent what you would like expression evaluated against, while the resultX fields are the values you want substituted if a match is found.

Anything you can do with an Oracle DECODE function, you could just as easily achieve with an IF-THEN-ELSE block. You would normally use a DECODE function over the IF-THEN-ELSE when you have a simple comparison or you prefer the readability of a DECODE function.

As a practical example, consider the small block of data below which might represent a subset of data from a multi-user system.

userid username power
10 john 1
11 cameron 2
12 al 5
13 simon 4
14 lucas 0
15 sally 3

If you issued the following SQL statement against that data, you should expect the output below:

SELECT userid, username, DECODE(power, 1, 'Registered', 2, 'Trusted', 3, 'Moderator', 4, 'Author', 5, 'Administrator', 'Pleb') As status FROM Users;

userid username status
10 john Registered
11 cameron Trusted
12 al Administrator
13 simon Author
14 lucas Pleb
15 sally Moderator

The caveat of using the Oracle DECODE function is that the expression must evaluate to a single value. As such, you can not use an evaluation which has multiple possible values. In such a circumstance, you would need to find a way (read: algorithm) to make each possible value evaluate to a single value. By doing so however, you are removing the simplicity of the DECODE function and an IF-THEN-ELSE block would probably suit better.

Next time you’re going to reach for the trusty IF-THEN-ELSE block by default, consider using a DECODE function – in the right circumstances, it’ll make your SQL simpler.

Oracle RETURNING Clause

The Oracle RETURNING clause was implemented as part of the Oracle 10g release and is used to return information about the effected rows after issuing Data Manipulation Language (DML) statements. Prior to Oracle 10g, you would have needed to work around not having this feature, most likely by issuing additional statements to the database.

The RETURNING clause has a few restrictions:

  • it is only available for use on tables, materialised views, normal views based on a single table or an expression based on the previous three items
  • it is only valid on a single-set aggregate. A single set aggregate is DML which only effects a single row or using an aggregate function in the RETURNING statement (such as SUM).

The general syntax for the RETURNING clause is:

INSERT INTO <table> (c1, c2, .., cn) VALUES (v1, v2, .., vn) RETURNING <expression> INTO <variables>
UPDATE <table> SET (c1) = (v1), (c2) = (v2), (cn) = (vn) WHERE <condition> RETURNING <expression> INTO <variables>
DELETE FROM <table> WHERE <condition> RETURNING <expression> INTO <variables>

This feature is particularly useful when INSERTing into a table, where the Primary Key is sourced from a sequence and fetched via a TRIGGER. In the below example, the ID of the newly inserted row is assigned to pContactID using the RETURNING clause. This is an elegant solution as it means you don’t have to SELECT the NEXTVAL from the sequence and assign that value to the ContactID during INSERT simply so you can return the new primary key value.

PROCEDURE Ins
(pContactID     OUT Contacts.ContactID%TYPE,
 pFirstname     IN Contacts.Firstname%TYPE,
 pSurname       IN Contacts.Surname%TYPE)
IS
BEGIN
 INSERT INTO Contacts
 (fname, sname)
 VALUES
 (pFirstname, pSurname)
 RETURNING ContactID INTO pContactID;
END;

You could just as easily use it to return the information about a row deleted, such as:

PROCEDURE Del
(pContactID     IN Contacts.ContactID%TYPE,,
 pFirstname     OUT Contacts.Firstname%TYPE,
 pSurname       OUT Contacts.Surname%TYPE)
IS
BEGIN
 DELETE FROM Contacts
 WHERE ContactID = pContactID
 RETURNING fname, sname INTO pFirstname, pSurname;
END;

Since the RETURNING clause is for use with aggregates, an example illustrating its use is in order. The below example modifies pContactID salary by pPercentageChange and subsequently returns the updated total company salary expenditure.

PROCEDURE UpdateSalary
(pContactID        IN Contacts.ContactID%TYPE,
 pPercentageChange IN NUMBER,
 pGrossSalary      OUT NUMBER)
IS
BEGIN
 UPDATE Contacts
 SET salary = salary * pPercentageChange
 WHERE ContactID = pContactID
 RETURNING SUM(salary) INTO pGrossSalary;
END;

The Oracle RETURNING clause provides the PL/SQL developer with a lot of flexibility. The real benefits however, come from the simplified PL/SQL and clarity gained in the code. If you’ve got a lot of application code or PL/SQL which isn’t utilising the power available to you – it might be time to undertake a clean up in your project.

Oracle Data Provider (ODP.net): Data Provider Internal Error (-3000/-3001)

During a recent release of a new ASP.net website, the launch went horribly wrong and required a rollback.

Setup

Front of house Back of house
  • Windows 2003 Server Standard
  • IIS6
  • Microsoft .net 1.1
  • Oracle Data Provider v10.1.0.301
  • Redhat Linux Enterprise R4
  • Oracle 10g Enterprise Release 2, clustered using RAC

Scenario

Whilst the code was in the development environment, we weren’t seeing any issues. Once the code was published to a staging environment and the load on the temporary under powered server increased, we started to see errors creeping in. At the time, it was written off as being a combination of Oracle 10g Release 1 Standard and the server simply not having the resources to handle the load. We had previously seen poorly written legacy code bring a Dual 3.2Ghz Xeon running Oracle 10g Standard Release 1 (dedicated server processes) to its knees with similar style random errors.

Searching online seemed to reveal a common trend; it was an Oracle Data Provider problem. Unfortunately, everything we found was related to the version 9 data provider – while we were already running version 10. After four developers spending a few hours trying to resolve the error, a support request was logged with Oracle via MetaLink. Over the following three hours and a continuous stream of phone and email correspondence with Oracle, one of their technicians informed us of a patch set available for our current Oracle Data Provider.

Patch Information

Patch Number #4355425
Description Oracle ODP.NET Patchset 10.1.0.3.04
Product Oracle Data Provider for .NET
Release Oracle 10.1.0.3
Bugs Addressed
4228597 OracleDataAdapter returning incorrect schema information
4205389 ODP.net hangs with multiple WHEN clauses on CASE statement
4190650 Direct path INSERT doesn’t work via ODP.net
4066828 Unmanaged exceptions return -3000 error without further information
4028378 Need attributes/methods on OracleParameter/OracleCommand classes
4020081 ODP.net -3000 errors under high load
3937454 Calling cancel before command execution causes an error
3930596 Output bind variable initialized with blanks using ParameterDirection.OUTPUT
3897454 Aborting selecting thread fails with internal error -3000
3893458 ODP internal error -3000 in ExecuteReader() method

Out of list of bug fixes, two items should be highlighted:

  1. 4020081: As we were running short of servers during the development phase, we had Oracle 10g Release 1 Standard installed on a standard desktop machine with a single hard drive. Once the application was released to testing, the Linux ‘load’ on this machine was regularly breaking 15-20. As such, this could have been contributing to the Data Provider Internal Error.
  2. 3893458: The legacy version of this application had been running on the v10.1.0.301 of the Oracle Data Provider for nearly a year without any issues. That code base made very limited use of PL/SQL stored procedures, while all new code was being funneled through PL/SQL. Strangely, the legacy code would have been firing the ExecuteReader() method, while the new code was firing ExecuteNonQuery(). If this was the cause directly, you would have expected those to be around the other way. I think it is worth listing here, as the decision to funnel everything through PL/SQL is a fundamental shift in the application architecture.

It should be noted that without the help of the Oracle Technician, we would have never found this patch on MetaLink in a timely fashion; which I would consider a serious shortcoming of the site. However, after downloading and applying the patch manually, the random errors immediately vanished.

There was a lesson learned from this experience, the Oracle Data Provider was discounted as a likely problem early on because we were using a newer version of the provider than that of the error reports we were seeing. Looking back on it, we should have immediately upgraded the Oracle Data Provider to the latest public release, simply to rule out a bug in an older version.

Guido van Rossum & Google Team Up

Guido van Rossum, the founder and creative power behind the ever popular Python programming language has accepted an offer from Google.

After reading, it seems people are divided, saying it could be a good and bad thing for Python. I am well and truly of the opinion it will be a good thing. It is a known fact that Google uses a huge amount of Python in their company. With the scale of their systems and data, you would have to assume this will lead to the improved performance of the language in the future.

Lets hope its a positive influence for the Python programming language in the future.