Sunday, December 13, 2009

Database Management Systems

Hi all,
The main purpose of the blog is to create a lot of interests in the students to try and solve the problems involved in DBMS at undergraduate level as well post graduate

Monday, August 24, 2009

ORACLE CEO's Salary $1



Bangalore: Software giant Oracle has informed in a regulatory filing, to cut the salary of its Chief Executive Larry Ellison to $1 in fiscal 2010 as compared to $1 million in the previous year. But according to Forbes, he will still remain as the fourth richest person in the world.



"The compensation committee recognizes that Ellison has a significant equity interest in Oracle, but believes he should still receive annual compensation because he plays an active and vital role in our operations, strategy and growth. Nevertheless, during fiscal 2010, Ellison agreed to decrease his annual salary to $1," said the company in a filing.

The compensation packages of the CEO include a base salary, an annual cash bonus and stock options.

In fiscal year 2009, the bonus and stock options comprised 97 percent of Ellison's overall compensation. According to the company, only 1.2 percent was his base salary and 1.8 percent was other benefits,.

His new $1 base salary puts him with the likes of Apple CEO Steve Jobs and Google co-founders Sergey Brin and Larry Page, who also take home the same package.

Larry Ellison, 64, had founded Oracle in 1977, and according to the SEC filing, he owns 1.18 billion shares of Oracle, which is 23.4 percent of the company's total stock.

Wednesday, August 12, 2009

Detecting a Memory Leak

To detect a memory leak
1. Create a CMemoryState object and call the Checkpoint member function to get the initial snapshot of memory.

2. After you perform the memory allocation and deallocation operations, create another CMemoryState object and call Checkpoint for that object to get a current snapshot of memory usage.

3. Create a third CMemoryState object, call the Difference member function, and supply the previous two CMemoryState objects as arguments. The return value for the Difference function will be nonzero if there is any difference between the two specified memory states, indicating that some memory blocks have not been deallocated.
The following example shows how to check for memory leaks:
// Declare the variables needed
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
oldMemState.Checkpoint();
#endif
// do your memory allocations and deallocations...
CString s = "This is a frame variable";
// the next object is a heap object
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
#ifdef _DEBUG newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "Memory leaked!\n" );
}
#endif
Notice that the memory-checking statements are bracketed by #ifdef _DEBUG / #endif
blocks so that they are compiled only in Win32 Debug versions of your program.
Courtesy: MSDN

Tuesday, April 07, 2009

Embedded SQL

Embedded SQL/Oracle Tutorial

Cursors

By now, if you have been following the tutorials closely, you should be quite familiar with inserting, updating, and deleting database records. The next step is to create querying functions (i.e., to handle SELECT operations).  We have intentionally left querying until last because there often are more steps to perform. Unlike the format of queries we typed into SQL*Plus, embedded SQL requires the use of cursors to successfully output the results of the query.

Cursors were invented to satisfy both the SQL and host programming languages. SQL queries handle sets of rows at a time, while C++, for example, handles only one row at a time. When we type the following SQL query into SQL*Plus:
 

SQL> select    driver_sin, count(exam_score)
   2 from      exam
   3 where     exam_type = 'L'
   4 group by  driver_sin;


we get the following output:

DRIVER_SIN COUNT(EXAM_SCORE)
---------- -----------------
 111111111                 1
 222222222                 2
 333333333                 3
 444444444                 1
In our embedded SQL code, we cannot simply specify:
 
EXEC SQL SELECT    driver_sin, count(exam_score)
         FROM      exam
         WHERE     exam_type = 'L'
         GROUP BY  driver_sin;


and expect C++ to output the results of the query. We have to fetch the results of this query into a cursor, and then output the results one at a time using C.

To use a cursor in embedded SQL, we must first declare it. We do this by using the DECLARE keyword, with the following syntax:
 

EXEC SQL DECLARE <cursor name> CURSOR FOR
SELECT ... FROM ...;


where the SELECT part of the statement specifies the query. Note that the above statement is only a declaration and the SELECT itself has not been executed yet. The declaration must occur before it is used. The scope of a cursor is the entire Pro*C++ program, but cursor statements (DECLARE, OPEN, FETCH, and CLOSE) must occur within the same precompiled unit. Therefore, for the entire program, each <cursor name> must be unique.

Once a cursor is declared, we have to open it in order to execute the query. To do this, we use the OPEN keyword, as follows:


EXEC SQL OPEN <cursor name>;


When we first open a cursor, it points to just before the first row (of the result). To retrieve rows (one at a time) which satisfy the SELECT query, we need to use the FETCH keyword. The syntax of the FETCH statement is:
 

EXEC SQL FETCH <cursor name> INTO :hostvar1, :hostvar2, ...;


Note that we have to first declare and open the cursor with cursor name before being able to use it in a FETCH statement.

After executing the FETCH statement, the cursor is set to point to the beginning of the next row of the answer set. When all rows have been fetched, sqlcode is set to 100 or 1403. Acknowledging this, we can write simple while loops which continuously fetch and print out tuple values for each row by testing sqlcode for the values 100 and 1403. You will see this in the example given below.

After all rows have been fetched, you can close the cursor with the command:
 

EXEC SQL CLOSE <cursor name>


A cursor can always be reused, so if you want to reuse your cursor, all you have to do is reopen it. The FETCH statement only moves forward in tables, so you might want to reopen a cursor to revisit and fetch previous rows in a table.
 
 

Sample Program

You should know enough about cursors by now to complete any homework involving embedded SQL.  Here is the Pro*C++ source code for maintaining the branch relation. In particular, note the subroutine called Show_Branch() which shows information for all branches.
#include <iostream.h>
#include <stdlib.h>                       // needed for atoi()
#include <stdio.h>                        // needed for gets()
#include <string.h>
#include <unistd.h>                       // needed for getpassphrase()
#include <iomanip.h>                      // needed for setw()
#define MAXBUF 50                         // maximum length of buffer
char line[MAXBUF];                        // buffer to hold stdin
EXEC SQL INCLUDE sqlca;                   // declarations for error checking
EXEC SQL WHENEVER SQLERROR    DO  print_error();
EXEC SQL WHENEVER SQLWARNING  DO  print_warning();
EXEC SQL WHENEVER NOTFOUND    DO  print_not_found();
void print_error()
{
  // display the error message returned by Oracle
  cout << "\n!! Unsuccessful operation.  Error code: " << sqlca.sqlcode;
  cout << "\n   Oracle Message: " << sqlca.sqlerrm.sqlerrmc << "\n";
}
void print_warning()
{
  // display the warning message returned by Oracle
  cout << "\n!! A warning occurred.   Error code: " << sqlca.sqlcode;
  cout << "\n   Oracle Message: " << sqlca.sqlerrm.sqlerrmc << "\n";
}
void print_not_found()
{
  // display the "row not found" message returned by Oracle
  cout << "\n!! Warning.  Row not found.  Error code: " << sqlca.sqlcode;
  cout << "\n   Oracle Message: " << sqlca.sqlerrm.sqlerrmc << "\n";
}
void Connect()
{
    // connect to database
    EXEC SQL BEGIN DECLARE SECTION;
        char userid[64];
        char password[64];
        char *DBname = "@ug";
    EXEC SQL END DECLARE SECTION;
    cout << "\nUsername: ";
    gets(userid);
    strcat(userid, DBname);
    strcpy(password, getpassphrase("Password: "));
    EXEC SQL CONNECT :userid IDENTIFIED BY :password;
}
void Insert_Branch()
{
  // Insert a tuple into the branch relation
  EXEC SQL BEGIN DECLARE SECTION;
    int        bid;
    VARCHAR    bname[20];
    VARCHAR    baddr[50];
    VARCHAR    bcity[20];
    int        bphone;
    short int  baddr_ind;
    short int  bphone_ind;
  EXEC SQL END DECLARE SECTION;
   cout << "\nBranch ID: ";
  gets(line);
  bid = atoi(line);
  cout << "\nBranch Name: ";
  gets(line);
  bname.len = strlen(line);
  strncpy((char *) bname.arr, line, bname.len);
  cout << "\nBranch Address: ";
  gets(line);
  baddr.len = strlen(line);
  strncpy((char *) baddr.arr, line, baddr.len);
  cout << "\nBranch City: ";
  gets(line);
  bcity.len = strlen(line);
  strncpy((char *) bcity.arr, line, bcity.len);
  cout << "\nBranch Phone: ";
  gets(line);
  if (strlen(line) != 0)
     bphone = atoi(line);         // phone number is not null
  else
     bphone_ind = -1;             // phone number is null;  set indicator
  EXEC SQL INSERT
           INTO    branch (branch_id, branch_name, branch_addr, branch_city,
                           branch_phone)
           VALUES (:bid, :bname, :baddr:baddr_ind, :bcity, :bphone:bphone_ind);
  //  The WHENEVER statement will handle the error processing, but
  //  to show the sequence of error messages, let's add the following.
  if (sqlca.sqlcode < 0)
     cout << "An error was detected.  The details are described above.\n";
  EXEC SQL COMMIT WORK;
}
void Delete_Branch()
{
  // Delete a tuple from the branch relation, given the branch id
  EXEC SQL BEGIN DECLARE SECTION;
    int  bid;
  EXEC SQL END DECLARE SECTION;
  cout << "Branch ID: ";
  gets(line);
  bid = atoi(line);
  EXEC SQL DELETE
           FROM   branch
           WHERE  branch_id = :bid;
  EXEC SQL COMMIT WORK;
}
 void Update_Branch()
{
  // Update the branch name, given the branch id
  EXEC SQL BEGIN DECLARE SECTION;
    int      bid;
    VARCHAR  bname[20];
  EXEC SQL END DECLARE SECTION;
   cout << "Branch ID: ";
  gets(line);
  bid = atoi(line);
  cout << "New Branch Name: ";
  gets(line);
  bname.len = strlen(line);
  strncpy((char *) bname.arr, line, bname.len);
  EXEC SQL UPDATE branch
           SET    branch_name = :bname
           WHERE  branch_id = :bid;
  EXEC SQL COMMIT WORK;
}
void Show_Branch()
{
  // Display information about branches
  EXEC SQL BEGIN DECLARE SECTION;
    int        bid;
    VARCHAR    bname[20];
    VARCHAR    baddr[50];
    VARCHAR    bcity[20];
    int        bphone;
    short int  baddr_ind;
    short int  bphone_ind;
  EXEC SQL END DECLARE SECTION;
  EXEC SQL DECLARE branch_info CURSOR FOR
           SELECT * FROM BRANCH;
  EXEC SQL OPEN branch_info;
  EXEC SQL FETCH branch_info
           INTO  :bid, :bname, :baddr:baddr_ind, :bcity, :bphone:bphone_ind;
  cout << setiosflags(ios::left);       // left justify the names to come
  cout << setw(10) << "ID"   << setw(15) << "NAME"  << setw(15) << "ADDRESS"
       << setw(15) << "CITY" << setw(15) << "PHONE" << "\n";
  cout << "--------------------------------------------------------------\n";
  while (sqlca.sqlcode >= 0  &&  sqlca.sqlcode != 100  &&
         sqlca.sqlcode != 1403)
   {
     bname.arr[bname.len] = '\0';       // null terminates the VARCHARs
     baddr.arr[baddr.len] = '\0';
     bcity.arr[bcity.len] = '\0';
     // display results;  keep the columns aligned reasonably well
     cout << setw(10) << bid       << setw(15) << bname.arr
          << setw(15) << baddr.arr << setw(15) << bcity.arr << setw(15);
     if (bphone_ind != -1)              // display phone number, if not null
        cout << bphone;
     else
        cout << " ";
     cout << "\n";
     EXEC SQL FETCH branch_info
              INTO  :bid, :bname, :baddr:baddr_ind, :bcity, :bphone:bphone_ind;
   }
  cout << "The last warning just signifies that the cursor fetched the "
       << "final record\n";
  EXEC SQL CLOSE branch_info;
  EXEC SQL COMMIT WORK;
}
int main()
{
  // simple text interface for above functions
  int  choice, quit;
  Connect();                        // connect to Oracle
  quit = 0;
  while (!quit)
    {
      cout << "\nPlease choose one of the following: \n";
      cout << "1. Insert branch\n";
      cout << "2. Delete branch\n";
      cout << "3. Update branch\n";
      cout << "4. Show   branch\n";
      cout << "5. Quit\n>> ";
      gets(line);
      choice = atoi(line);
      printf("\n\n");
      switch (choice)
        {
          case 1:  Insert_Branch();
                   break;
          case 2:  Delete_Branch();
                   break;
          case 3:  Update_Branch();
                   break;
          case 4:  Show_Branch();
                   break;
          case 5:  quit = 1;
          default: exit(0);
        }
     }
  EXEC SQL COMMIT WORK RELEASE;     // Commit and free any locks held.
  // Any additional non-SQL/non-Oracle work can go here.
}
Compile and run the code. You can now test modifications (insert, update, and delete) to the branch relation without having to start up an SQL*Plus session.

Although our example tested sqlca.sqlcode for the values 100 and 1403 in the Show_Branch() function, we could have used error trapping instead and done something like this:
 

EXEC SQL WHENEVER NOTFOUND DO BREAK;
while(1)  {
. . .
EXEC SQL FETCH branch_info
         INTO  :bid, :bname, :baddr:baddr_ind, :bcity, :bphone:bphone_ind;
. . .
}
/* restore WHENEVER NOTFOUND to what we had before */
EXEC SQL WHENEVER NOTFOUND DO print_not_found();



Embedded SQL/Oracle Tutorial  - Cursors


Friday, April 03, 2009

'Telecom sector can create 25 Million jobs'



By    siliconindia news bureau

New Delhi: Driving attention to the telecom sector, major telecom players have proposed for deployment of mobile broadband financed by private players, which would create 25 million jobs. Global GSM players like AT&T Mobile, Ericsson, Alcatel Lucent, Orascom, MTN Group and Sunil Bharti Mittal of Bharti Airtel have submitted the proposal to PM Manmohan Singh, to endorse it at the G20 meet.

The proposal also highlighted that the move will boost global GDP by around four percent. "The initiative is centered on replicating the success story of GSM and making access to the Internet via mobile broadband devices ubiquitous. The broad economic impact of this is well established in research. In emerging economies, a 10 percent increase in mobile penetration boosts annual GDP growth by 1.2 percent," said the letter.


Highlighting the efficacy of the mobile firms, the companies provide voice and basic data services to over four billion consumers, on networks that cover over six billion. A 10 percent increase in mobile penetration will boost annual GDP growth by 1.2 percent. In return for this, the mobile industry has asked for two key enabling actions from the G20 governments.

Thursday, April 02, 2009

VB Tutorial

Following is an online tutorial:

http://www.vbtutor.net/vbtutor.html

http://www.vbtutor.net/vb2008/vb2008tutor.html

Sample Applications can be downloaded with source code:

http://www.vbtutor.net/VB_Sample/sample.html

http://www.vbtutor.net/VB_Download/vbcodes.htm

http://www.vbtutor.net/VBGuide/vbguide.html

Windows Magical BUGS!!!!!!!!!!



Try out…….. Its too Interesting!!!!!!!!!

 

 

Microsoft fails to solve these problem- Really Interesting

MAGIC #1

An Indian discovered that nobody can create a FOLDER anywhere on the computer  which can be named as "CON". This is something pretty cool...and unbelievable... At Microsoft the whole Team, couldn't answer why this happened!
TRY IT NOW ,IT WILL NOT CREATE " CON " FOLDER


MAGIC #2
For those of you using Windows, do the following:

1.) Open an empty notepad file
2.) Type "Bush hid the facts" (without the quotes)
3.) Save it as whatever you want.
4.) Close it, and re-open it.

is it just a really weird bug? :-??


MAGIC #3
Microsoft crazy facts

This is something pretty cool and neat...and unbelievable... At Microsoft the whole Team, including Bill Gates, couldn't answer why this happened! It was discovered by a Brazilian. Try it out yourself...

Open Microsoft Word and type

=rand (200, 99)

And then press ENTER
then see the magic...............................

-~----------~----~----~----~------~----~------~--~---

Wednesday, April 01, 2009

U.S. private employers cut 742,000 jobs in March By siliconindia news bureau


New York: Downturn-ridden U.S. economy continues to fall further and the number of job losses is getting bigger every month. As per a report by ADP employer Services, private employers in the country have cut a record 742,000 jobs in March over 706,000 job-cuts in February.



According to the analysts, the big drop foreshadows a huge decline in the non-farm payroll reading in the government's employment report that will be released on Friday.

"It's a terrible number. It is almost a loss of three quarters of a million jobs which is possibly the highest we have seen so far over the length of this crisis," said Matt Esteve, foreign exchange trader with Tempus Consulting in Washington.

After the news of the huge job losses in March, U.S. stock futures and the dollar have fallen, while U.S. treasury bonds regained some of their lost ground.

Code here to gain money + recognition

Click the link below:

https://codesniper.forge.funambol.org/?utm_campaign=iCar%2C%20CTIA%2C%20new%20screencam%2C%20free%20whitepaper%20%26%20Storm&utm_medium=Email&utm_source=VerticalResponse&utm_term=Code%20Sniper

SOME USEFUL NEWS - Read and Make Money on your Interest

March/April 2009 | Spring Issue | Click to view this message in a browser

Welcome to the Spring issue of Funambulletin, where we strive to bring you the best, most interesting and entertaining news about mobile open source. Exclusive Funambol Introduces World's First Touchless iCar Borrowing from the iPhone, Funambol is premiering the world's first finger gesture operated vehicle. With no steering wheel, it makes driving a snap. Check out the press release and test drive video a day before anyone else. Funambol Events See Funambol at CTIA Funambol is showcasing its next major version, MobileWe v8, at CTIA, April 1-3. It includes an all new AJAX portal that makes it easy to sync content from billions of mobile phones with the Internet cloud and popular email systems and desktop apps. For more information about our doings at CTIA and to arrange a meeting, see our advisory. Funambol Video Funambol v8 Open Source MobileWe Portal Screencam Not headed to CTIA? See a screencam of the new portal on Youtube, here's the long and short of it. Free White Paper Mobile Sync, the New World Order This new white paper describes the trends that are making cloud sync compelling. It also discusses the requirements for a mobile sync solution and how open source satisfies these requirements. Get the free white paper instantly after website registration. Product Update New Phone Pack Supports BlackBerry Storm Funambol just completed work on its new monthly 'phone pack' that supports the latest mobile devices. It supports the BlackBerry Storm as well as lays the foundation to support other touchscreen devices more quickly. The new phone pack will be made available shortly on the free myFUNAMBOL portal. We will issue a press release in the next few days to signal that the phone pack is installed and ready for action. Community News New Funambol Forge Home Page Our new forge has had an extreme home (page) makeover, check it out. It shows how dynamic our community is and makes it easier to download software and access other content. Our downloads and community traffic have reached record levels since the home page was redesigned a few weeks ago. Thanks to everyone who provided feedback on the new home page and helped make it happen. Open Source Update Write Code, Get Paid We recently suggested several new Code Sniper projects that community developers can work on and get paid and recognized for their contribution. These include a Syncml Graphic Client for Maemo, GNOME Eplugin for Evolution, LinkedIn Contacts Client, Skype PIM Client, Eclipse integration and Netbeans integration. Check out the Code Sniper page for details. Funambol Customers Millions of Users Adopting Funambol There has recently been a surge in customers, ranging from established companies to startups, who have deployed Funambol Carrier Edition. These customers collectively have millions of users and have implemented some highly innovative uses of mobile sync and push email. We will be issuing a press release about them in the next few days as well as blogging and tweeting about them. Thought Leadership Smart Cloud Syncing, the Next Mobile Holy Grail? Check out this interesting OSTATIC article about smart cloud app syncing as the next mobile frontier. Fun Tweet Favorite Tweet of the Month We love reading everyone's tweets, but this one caught our attention: "iPod Touch Sets Kid's Pants on Fire. I feel bad for the kid, but it's an amusing story."

In This Issue...
Funambol Introduces World's First Touchless iCar
See Funambol at CTIA
Funambol v8 Open Source MobileWe Portal screencam
Mobile Sync, the New World Order whitepaper
New Phone Pack supports BlackBerry Storm
New Funambol Forge Home Page
Code Sniper: Write Code, Get Paid
Customer Update: Millions of Users Adopting Funambol
Smart Cloud App Syncing
Favorite Tweet of the Month
Code Sniper Community Program
Funambol offers cash bounties for developers to extend our open source capabilities. Check out the list of projects and become a Code Sniper.
Upcoming Events
CTIA Wireless 2009
April 1-3, 2009, Las Vegas
Funambol is showcasing its new Funambol v8 Open Source MobileWe Portal for billions of phones. Check out this advisory for more information and to arrange a meeting.
Stay in touch
Stay in touch with Funambol following the stream on Twitter.
About Funambulletin
Funambulletin is Funambol's periodic newsletter that contains mobile open source community and industry news, views, tips and happenings. We hope that you find Funambulletin to be informative, useful and entertaining. If you have any suggestions or contributions, please contact Stefano Maffulli, Funambol community manager, at maffulli-at-funambol com.
About Funambol Copyright (C) 2009 Funambol. All rights reserved. Funambol is the leading provider of open source push email and mobile sync worldwide. Funambol open source software has been downloaded three million times by 50,000 developers and project participants in 200 countries. The commercial version of Funambol has been deployed at service providers, mobile operators, portals, device manufacturers and ISVs including customers such as 1&1, Earthlink, AOL and CA, Inc. Funambol is headquartered in Redwood City, CA with an R&D center in Italy. For more information, please visit www.funambol.com.

iCar, CTIA, new screencam, free whitepaper & Storm

If you no longer wish to receive these emails, please reply to this message with "Unsubscribe" in the subject line or simply click on the following link: Unsubscribe


Click here to forward this email to a friend

Funambol Inc
643 Bair Island Road, Suite 305,
Redwood City, California 94063
US

Read the VerticalResponse marketing policy.

Try Email Marketing with VerticalResponse!


Monday, March 30, 2009

New virus infects ATM , steals money from banks

Moscow: Automatic Teller Machines (ATM) may not be a safe way of transaction anymore as a new software virus has been found out which infects ATMs to steal money from bank accounts of their users. Doctor Web and 'Kaspersky Lab, two major anti-virus software producers have discovered such virus in the networks of several bank ATMs, which is able to collect information from bank cards.



This is a malicious program intended to infect and survive in ATMs. It is possible that new software will appear, aimed at illegitimately using banking information and removing funds," an official of the Kaspersky Lab was quoted as saying by RIA Novosti news agency.

According to the official, the virus is a Trojan which is able to infect the popular American Diebold brand of ATMs, used in Russia and Ukraine. Judging by the programming code used, there is a high probability that the programmer comes from one of the former Soviet republics.

The computer security experts say the number of infected ATMs is minimal but individual bank cardholders will not be able to detect whether an ATM is infected or not. However, banks can run security software to find out if their machines are at risk.

Courtesy: http://www.siliconindia.com

Chinese hackers infiltrate Indian embassy data

Toronto: China based hackers have infiltrated computers and stolen documents from hundreds of government and private offices around the world, including those of the Indian embassy in the U.S. and the Dalai Lama's organization, Canadian researchers said.



A vast electronic spying operation system, which infiltrated the computers, was being controlled from computers based exclusively in China, said the researchers in a report to be issued shortly. But they could not say conclusively that the Chinese government was involved. The group did also not identify the Indian embassies which were targeted.

The office of the Dalai Lama in India had asked the researchers based at the Munk Center for International Studies at the University of Toronto, to examine its computers for signs of malicious software, or malware.

Their examination unearthed a broader e-spying operation that, in less than two years, has infiltrated at least 1,295 computers in 103 countries, including many belonging to Indian embassies as well as the Dalai Lama's Tibetan exile centers in India, Brussels, London and New York.

The researchers believed that the e-spying operation, which they called GhostNet, had hacked into the computer systems at embassies of countries like Pakistan, Germany, Indonesia, Thailand and South Korea. The networks at foreign ministries of Bhutan, Bangladesh, Latvia, Indonesia, Iran and the Philippines, had been found similarly hacked.

Courtesy: http://www.siliconindia.com

Thursday, March 19, 2009

Handling Large Objects (LOB) - Oracle Database 10g

Handling Large Objects (LOB) - Oracle Database 10g

Large Objects (LOB)

Large Objects (LOBs) are a set of datatypes that are designed to hold large amounts of data. A LOB can hold up to a maximum size ranging from 8 terabytes to 128 terabytes depending on how your database is configured. Storing data in LOBs enables you to access and manipulate the data efficiently in your application.

BLOB - Binary Large Object
Stores any kind of data in binary format. Typically used for multimedia data such as images, audio, and video.

CLOB - Character Large Object
Stores string data in the database character set format. Used for large strings or documents that use the database character set exclusively. Characters in the database character set are in a non-varying width format.

NCLOB - National Character Set Large Object
Stores string data in National character set format. Used for large strings or documents in the National character set. Supports characters of varying width format.

BFILE - External Binary File
A binary file stored outside of the database in the host operating system file system, but accessible from database tables. BFILEs can be accessed from your application on a read-only basis. Use BFILEs to store static data, such as image data, that does not need to be manipulated in applications. Any kind of data, that is, any operating system file, can be stored in a BFILE. For example, you can store character data in a BFILE and then load the BFILE data into a CLOB specifying the character set upon loading.

Following are the examples, which I tried my self with oracle database 10g on Linux installation and pasted the contents. I have also put the neccessary comments for your understanding. Kinly let me know in case you have any doubts.

Storing a image file in oracle database table using DBMS_LOB package

Step 1) create a table

SQL> create table loadalbum
2 (name varchar2(100),
3 image blob);

Table created.

Step 2) Create a Directory object in database which will point to operating system directory.

SQL> CREATE OR REPLACE DIRECTORY DOCUMENTS AS '/dy/oracle/product/db10g/photo';

Directory created.

Step 3) Use the following procedure to insert a BLOB (image file) into database.
Note: The file (Sunset.jpg), which we are inserting into table should be present in DOCUMENTS directory location (/dy/oracle/product/db10g/photo) created above.

declare
l_blob blob;
l_bfile bfile;
begin
insert into loadalbum values ( 'Sunset', EMPTY_BLOB() )
// First create a Emply binary large object
returning image into l_blob; // and get a reference
l_bfile := bfilename( 'DOCUMENTS', 'Sunset.jpg' ); // Get the pointer to a file in directory
dbms_lob.fileopen( l_bfile ); // Open file
dbms_lob.loadfromfile( l_blob, l_bfile, dbms_lob.getlength( l_bfile ) );

dbms_lob.fileclose( l_bfile );
end;

SQL> select count(*) from loadalbum;

COUNT(*)
———-
1

Doing bulk upload of images to database.

You can use SQL*Loader utility to bulk upload regular text data. Same utility can be used to bulk upload images as well. Follow below steps to bulk up load the images

Step 1) Create a table

CREATE TABLE photoalbum (photolob BLOB);

Step 2) Create a file (example photos.txt ) which will contain list of images to be uploaded.

bash-2.05$ cat photos.txt
Winter.jpg
Water_lilies.jpg
Sunset.jpg
Blue_hills.jpg

Step 3) create a control file required by SQL*Loader to upload data. Create new file called loadphotos.ctl and insert following content into it.
load data
infile photos.txt
into table photoalbum
(ext_fname filler char(200),
photolob lobfile(ext_fname) terminated by EOF)

The meaning of above code is
"please load the data listed in the file photos.txt into a table called photoalbum. The data will be loaded into the column of that table called 'photoblob' and has lobfile characteristics… that is, it's binary data. Expect the file names for the binary files being loaded to be up to 200 characters in length. When you reach the end of the list of photos, terminate the load process".

Step 4) Run SQL*Loader

Please note that photos.txt is used in control file and we are not giving absolute path, but relative path. So control file and photos.txt should be in same directory. And so also all images. See below.

bash-2.05$ pwd
/dy/oracle/product/db10g/photo
bash-2.05$ ls -lrt
total 576
-rw-r–r– 1 db10g oinstall 105542 Jun 2 23:43 Winter.jpg
-rw-r–r– 1 db10g oinstall 83794 Jun 2 23:43 Water_lilies.jpg
-rw-r–r– 1 db10g oinstall 71189 Jun 2 23:43 Sunset.jpg
-rw-r–r– 1 db10g oinstall 28521 Jun 2 23:43 Blue_hills.jpg
-rw-r–r– 1 db10g oinstall 127 Jun 2 23:46 loadphotos.ctl
-rw-r–r– 1 db10g oinstall 54 Jun 2 23:48 photos.txt

bash-2.05$ sqlldr system/manager control=loadphotos.ctl

SQL*Loader: Release 10.2.0.1.0 - Production on Sat Jun 2 23:48:21 2007Copyright (c) 1982, 2005, Oracle. All rights reserved.Commit point reached - logical record count 4The above message shows that data is uploaded correctly. You can check the log file generated by SQL Loader at same location.SQL> select count(*) from photoalbum
2 ;

COUNT(*)
———-
4

Uploading Word Document to oracle database

You can use database tables for storing work documents as well. Please follow the below steps for doing the same

Step 1) Create table

CREATE TABLE my_docs
(doc_id NUMBER,
bfile_loc BFILE,
doc_title VARCHAR2(255),
doc_blob BLOB DEFAULT EMPTY_BLOB() );
// Default value will be empty binary large object

Step 2) Create directory object

SQL> CREATE OR REPLACE DIRECTORY DOC_DIR AS '/dy/oracle/product/db10g/doc';

Directory created.

Step 3) Create a procedure for uploading the file. Here inputs will be file_name and file_id.

Create or replace PROCEDURE load (in_doc IN VARCHAR2, in_id IN NUMBER) IS

temp_blob BLOB := empty_blob();

bfile_loc BFILE;
BEGIN
bfile_loc := BFILENAME('DOC_DIR', in_doc);

INSERT INTO my_docs (doc_id, bfile_loc, doc_title) VALUES (in_id, bfile_loc, in_doc);
SELECT doc_blob INTO temp_blob FROM my_docs WHERE doc_id = in_id FOR UPDATE;
DBMS_LOB.OPEN(bfile_loc, DBMS_LOB.LOB_READONLY);
DBMS_LOB.OPEN(temp_blob, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.LOADFROMFILE(temp_blob, bfile_loc, dbms_lob.getlength(bfile_loc));

DBMS_LOB.CLOSE(temp_blob);

DBMS_LOB.CLOSE(bfile_loc);

COMMIT;
END load;

Step 4) Suppose I want to uplaod a .doc file present in the DOC_DIR directory (/dy/oracle/product/db10g/doc at OS level) created above.
The doc name is advait.doc.

Execute the above procedure as given below.

SQL> exec load('advait.doc', 1);

PL/SQL procedure successfully completed.

SQL> select count(*) from my_docs;

COUNT(*)
———-
1

The docs advait.doc will be saved in database table.

Updating LOB column of database table

Step 1) Create a table
CREATE TABLE book
(title VARCHAR2(40),
author VARCHAR2(40),
text CLOB,
author_pic BLOB);

Table created.

SQL>

Step 2) Insert some data

SQL> INSERT INTO book VALUES
2 ('My Book','Advait',EMPTY_CLOB(), EMPTY_BLOB());

1 row created.

Step 3) Update column using PL/SQL procedure

DECLARE
my_text_handle CLOB;
my_buffer VARCHAR2(4000);
my_add_amt NUMBER := 0;
my_offset INTEGER := 1;
BEGIN
my_buffer := 'This is my book';
my_add_amt := length(my_buffer);
SELECT text
INTO my_text_handle
FROM book
WHERE title = 'My Book' FOR UPDATE;

DBMS_LOB.WRITE(my_text_handle, my_add_amt, my_offset, my_buffer);
COMMIT;
END;

PL/SQL procedure successfully completed.

SQL>

SQL> select text from book;

TEXT
——————————————————————————–
This is my book

This can hold 4G of characters.


Courtesy: Internet Weblink

Monday, March 09, 2009

TCS likely to lay off 1,300 staffers



Chennai: India's IT major Tata Consultancy Services (TCS) will lay off around 1,300 employees - less than a percent of its global workforce- over the next few months, as these employees failed to meet performance standards, a company spokesperson said. The company has a total headcount of around 1.3 lakh.



Lay-offs have started at the company's development centers in Chennai, where over 200 employees have been asked to leave in the last fortnight, said TCS employees on condition of anonymity, as reported by The Economic Times.

A member of the TCS corporate communication team confirmed the development to the daily but did not put a number or place to it. "This is mostly employees who have been given a second chance to improve and haven't. They will be sent over a period, in the next few months. This will constitute less than a percent of our global workforce. We had to let go of 500 people last year on performance issues," the corporate communication team member said.

This comes less than a week after the company's CEO S Ramadorai said the company would review the variable pay component for its employees and also increase the working hours.

Asked about job cuts, he had said the company wasn't planning to cut jobs immediately but might have to if the situation worsened.

Employee expenses make up at least 53-54 percent of the company's total cost. Going by its analyst presentation for the third quarter ended December 2008, TCS had a total employee count of 1,30,343.

Wednesday, March 04, 2009

Oracle and Visual Basic using ADO - Sources: http://www.vb6.us/tutorials/oracle-and-visual-basic-using-ado

VB6 tutorial explains how you can access an Oracle database from within Visual Basic. It is a bit short as it was thrown together from a post on the vbforums.com page. However if you check out the Sample VB6 and Oracle Source Code that goes along with it. You should be able to easily understand what is going on. Read on and enjoy as you develop your Visual Basic Oracle application.

Oracle databases have been around for years, and although they are not as popular as their Microsoft counterpart, many business rely on Oracle backends for all their needs. Because of this, we must know how to interface with an Oracle database from within our VB6 application. This VB6 tutorial will walk us through exactly how to do this.

To access an Oracle database it is very similar to how you access any other database. We can simply use an ADO Connection object. We set the provider to be our Oracle provider and setup our connection string and password.

  1. Set dbConn = New ADODB.Connection
  2. With dbConn
  3. .Provider = "OraOLEDB.Oracle"
  4. .Properties("Data Source") = "DatabaseName"
  5. .Properties("User Id") = "someuser"
  6. .Properties("Password") = "somepassword"
  7. .Open
  8. End With

After we setup the connection all we do next is setup an ADO Command object that will be used with our oracle database. This is the same things we do for any Visual Basic database application.

  1. Set Cmd = New ADODB.Command
  2. Set Cmd.ActiveConnection = dbConn
  3. With Cmd
  4. .Parameters.Append .CreateParameter(, adVarChar, adParamOutput, 50)
  5. .Parameters.Append .CreateParameter(, adNumeric, adParamOutput)
  6. End With

Now is where things start being specific to our Oracle database. Getting a result set back from an Oracle SP is not as simple as it is in SQL Server. The results must come back to the calling program in something called a reference cursor (ref cursor). This will discuss what a ref cursor is and how to implement them and get data back.

Oracle creates an implicit cursor for every select query (I think that is the same for any database system). The cursor is simple the recordset results. If you are not going to use that result set for anything else (ie: to generate another query to execute) then you do not need to declare a cursor. But to get the result set out of Oracle you need something that is called a ref cursor. This ref cursor is more or less the same as and ADO recordset. You declare the ref cursor in code some where on the Oracle database, that ref cursor (sort of a structure in .Net) is then listed as an In and Out parameter of the SP.

You generate the select statement you want to run then open the ref cursor you created as follows:

  1. Open cRefCur For
  2. Select ....... (columns form whatever tables)
  3. From (table names)
  4. Where (conditions and Joins).
Standard SQL here with one big exception since if using Oracle 8i or earlier, Oracle at that release level did not support the Inner and Outer Join statements. You must use the Oracle version of them. Inners are just and equal sign as in Sales.ProductID = Prodcuts.ProductID. The Outer join is a lot messier, outer joins use the same equals sign and also a plus (+) sign on the deficient side of the equal sign.

This is the way to create the cursor:

First we create a package that will hold all the different return types:
  1. CREATE OR REPLACE PACKAGE cv_types AS

  2. TYPE WellData IS RECORD(
  3. WellName Varchar2(50),
  4. ResultsCount Number
  5. );
  6. TYPE CV_WEllData IS REF CURSOR RETURN WellData;

  7. End;
  8. /
Next we create a stored procedure that will use that ref cursor declared above:
(This procedure does not have any inputs, only output paramters).
  1. Create Or Replace Procedure WellCounting (
  2. pWellName OUT VARCHAR2,
  3. pCount OUT NUMBER,
  4. rsWellData IN OUT cv_types.CV_WEllData)

  5. AS

  6. BEGIN
  7. Open rsWellData For
  8. Select
  9. Wells.WELLNAME,Count(RESULTS.WELLID)
  10. Into
  11. pWellName,
  12. pCount
  13. From
  14. Wells, Results
  15. Where
  16. Wells.WellID = Results.WellID
  17. group by
  18. WEllName;

  19. EXCEPTION
  20. WHEN OTHERS THEN
  21. ROLLBACK WORK;
  22. RAISE;

  23. End WellCounting;
  24. /
We can then call the stored procedure from VB as shown in the included VB Projects.

An example of a stored procedure with input parameters is here:
  1. Create Or Replace Procedure OneWellCount (
  2. pWellID IN Number,
  3. pWellName OUT VARCHAR2,
  4. pCount OUT NUMBER,
  5. rsWellData IN OUT cv_types.CV_WEllData
  6. )

  7. AS
  8. BEGIN
  9. Open rsWellData For
  10. Select
  11. Wells.WELLNAME,Count(RESULTS.WELLID)
  12. Into
  13. pWellName,
  14. pCount
  15. From
  16. Wells, Results
  17. Where
  18. Wells.WellID = pWellID And
  19. Wells.WellID = Results.WellID
  20. group by
  21. WEllName;
  22. EXCEPTION
  23. WHEN OTHERS THEN
  24. ROLLBACK WORK;
  25. RAISE;

  26. End OneWellCount;
  27. /
We can also test these procedures (and ref cursors) from the SQL*Plus prompt by doing the following:
  1. Enter the command SET SERVEROUTPUT ON;
  2. Now we set up variables to hold data going into and out of the SP:
    Assuming we are using the first SP displayed, the we will need 3 variables:
    VARIABLE P1 VARCHAR2(50) This is because the field we are returning is 50 chars
    VARIABLE P2 Number This is a number coming back from the SP;
    VARIABLE P3 REFCURSOR This will hold the result set that is coming back
  3. From the SQL prompt enter:
    EXECUTE WellCounting( :P1, :P2, :P3);
  4. If the procedures completes successfully we can now display the output.
    The variable P1 and P2 will hold the last Well Name and number of results
    for that well name. The variable P3 will hold the complete recordset that
    is being returned. To display that result in SQL*Plus enter:
    Print P3

Naming Conventions in VB6.0


Introduction

I'm going to give you a little warning right from the start. The use of naming conventions is a religious issue for many programmers - sometimes ranking as high as the age-old goto debate or the choice of language. Some like naming conventions and some hate them. Most large programming organizations, however, do use them. I also think that many of those that passionately hate having naming conventions imposed on their work would probably (perhaps grudgingly) admit their usefulness.

Like many other "standards", what's more important than any particular naming convention, is that you choose a naming convention and use it faithfully. While you can probably get away with using your kids names for variable names in a 100 line program, you're inviting chaos if you take that approach with any serious application.

I will state one thing as a rule up front. Use Option Explicit. If you're new to Visual Basic and not familiar with it - its a feature that requires you to declare each variable in your program. Without Option Explicit, every time you type a new variable name, VB will create a new variable for you. As you can imagine, this can create bugs that are extrememly difficult to find if you happen to mistype a variable name somewhere. Other than pure laziness, there's simply no excuse for not using Option Explicit, so I have absolutely no sympathy for you if you ever have a bug caused by letting the compiler create a variable you didn't intend to create.

In the rest of this page, I'll describe the standards I've used for naming procedures, variables, and other objects of various types. Feel free to use my convention or invent your own.

Choosing Identifier Names

Most of the papers and books I've read that cover naming conventions spend a lot of time covering things like prefixes for different data types, etc., and neglect to cover the most basic concept - creating a good name for an identifier. Sure, it can help to use variable data type prefixes, but it doesn't help much if the name of your loop counter is intBunny and the procedure that contains the loop is called strDoSomething.

If you've done a decent job designing the application and the code, it doesn't take much effort to come up with decent names for the identifiers. The only problem that you're likely to run into is that the names may become excessively long. While very long names can be tiresome to use, its my opinion that you're better off to take the time to type an extra character or two than to use a meaningless or hard to interpret name.

Let's take a look at an example of how using appropriate variable names can help you write better code. Have you ever seen something like this:

For i = 0 To 10
For j = 1 To 100
List1.AddItem x(j, i)
Next
Next
Its more likely than not that in this case the array indexes have been reversed inside the inner loop. The programmer probably meant to do this:
    List1.AddItem x(i, j)
Its easy to eliminate this problem before its created by giving the loop indexes more meaningful names:
For iDivisionIdx = 1 To iDivisionCount
For iDistrictIdx = 1 To iDistrictCount
lstCustomers.AddItem sCustNames(iDivisionIdx, iDistrictIdx)
Next ' iDistrictIdx
Next ' iDivisionIdx
There's no confusion now over what loop index we're dealing with. Not only has the problem of transposing the indexes been elimiated - the entire loop construct is easier to read and understand because the names reflect the data being used.

Here are a few things to consider when naming identifiers in general:

  • Use a name that represents the data or the function.
    The name chosen should represent the data being used. If you are creating a variable that represents the total number of employees, EmployeeTotal or EmployeeCount would be good names.
  • Use abbreviations consistently.
    While its not necessary to have variable names that are 30 characters long, don't go overboard in abbreviating names. "Tm", for example, is only two characters shorter than "Time" and much less readable. There some common tags that are often used, such as Num for Number, Idx for Index, and so on. Feel free to use these if you wish, but if you do, use them consistently. Don't use Num some of the time and Number or Count at other times.
  • Make the name readable.
    A good rule to apply here is that you should be able to read your code to someone over the phone and have them be able to write it down without asking you for spellings.
  • Use a noun for variables.
    Pick a word that represents the data. This will make the code somewhat self-documenting and considerably easier to read.
  • Use a noun and a verb for procedures.
    If a procedure performs an action on an object, use a verb describing the action and a noun describing the object. For example, if a procedure adds a new contact to a database, "AddContact" might be an appropriate name.
  • Use caution with temporary variables.
    This is an area that can often cause problems such as the loop index error shown earlier. You may often need a temporary variable, such as a loop index or dummy variable to hold a return value from a function that you don't need. However, consider this: There's really no difference between a temporary variable and any other type of variable. They are all temporary since they only exist in the memory of the computer while the program is running and are always an abstraction created for the benefit of the programmer. The computer doesn't care what name you use, so why not take the time to type an extra character or two and use a meaningful name.

Naming Procedures

In a large, complex program, you may have hundreds or thousands of procedures. Using a naming convention and good identifiers can make your job of finding and using the procedures considerably easier.

One standard that is commonly used for procedure names is to use a verb describing the action performed followed by a noun describing the object acted upon. I have to say that I'm not particularly fond of this convention, mainly because it makes it difficult to find a procedure in an alphabetical listing. If you are using "Get" as a prefix to functions which return values (such as GetWindowText), you'll end up with a long list of GetThis and GetThat procedures. I've always thought that it makes more sense to use the same technique but to reverse the noun and the verb. GetWindowText would become WindowTextGet. This groups all the procedures associated with a particular object together. Unfortunately (for me anyway), I'm probably the only person to have attempted to use such a convention - so make your own choice to be consistent with the rest of the world or make up your own standard. Perhaps something else entirely works best for you.

Regardless of the naming convention you choose, there are a few things which a procedure name should do for you:

  • Use a name that represents an object and an action.
    Whether you use verb-noun or something else, the name of the procedure should indicate what the procedure does and what it does it to or with.
  • Be consistent in the order of the words.
    If you're going to use verb-noun, always use verb-noun. If you mix and match the two, you're only making your own life harder. While you may be able to remember all of the procedure names in a program with 100 procedures, you are unlikely to accomplish the same feat in a program with 1,000 or 10,000 procedures.
  • Be consistent in the verbs and nouns used.
    Just as you should be consistent when naming variables, you should also be consistent when naming procedures. If you're going to use SetFirstName, also use SetLastName rather than AssignLastName.
There's one other thing I'll mention which crosses the line between a coding standard and a naming convention. A well written procedure should do one task. If it does this, it will be easy to create a name for it. On the other hand, if the procedure does six things to four different objects, you may end up with a name like "AddCustomerAndUpdateRepPhoneAndFaxNumber". If you end up with a procedure name that looks like a run-on sentence, you probably haven't written a good procedure. If you need a name like "DoABunchOfStuff", you've almost certainly written a poor procedure. Before fudging a half-baked name, take another look at the code.

Naming Variables

Clearly its important with variables, just as with procedures and all identifiers, to use a name that is readable and representative of the data in use. There is, however, a debate among programmers over the use of various means of identifying variables by data type and usage. Some programmers like to use prefixes to identify the data type of the variable, while others prefer to use type declaration characters, and still others use neither and omit data type identification from the name entirely. The closest thing you'll find to a "sanctioned" naming convention for variables can be found in the MSDN/Visual Basic Starter Kit on the VB4 Professional edition CD under Visual Basic Programming Conventions from Microsoft Consulting Services.

I happen to like using data type prefixes, although I don't follow the Microsoft standards in all cases. Here's why:

  • The code is easier to read.
    I find that type declaration characters distracting when reading a code listing and difficult to verbalize.
  • You aren't bound to VB's data types.
    If you wish to define "hWnd" as a prefix for window handles, you can do so without breaking the standard.
  • You can design your own standard.
    The convention published by Microsoft specifies using "int" as a prefix for integers. I happen to prefer using just "i" - it saves a fair amount of typing for one of the most frequently used data types without sacrificing readability.
  • Some of the data types introduced in VB4 have no type declaration character.
    While I don't expect VB to drop the type declaration characters entirely in future versions, I also don't expect type declaration characters to be supported for any future data types. Also, many of the variables you work with are object variables which also have no type declaration character.
There are two other notable sets of tags I use for variable names.

The first is a prefix indicating the scope of the variable. I use "m" for module level variables and "g" for global variables. These tags not only identify the scope of the variable but also avoid name collisions and name shadowing between variables at different scopes.

The second is a prefix for parameters. I use this to avoid naming collisions between parameters and local variables and to distinguish between input and output variables. Input parameters are prefixed with "p" and output with "rp".

By using these additional modifiers, I can normally be sure that I never two variables in scope with the same name.

Modifier Tables

Here are most of the modifiers I use, grouped as follows:
  • Data Type Modifiers
  • Scope Modifiers
  • Miscellaneous Modifiers
  • Control Tags
  • DAO Objects

Data Type Modifiers

The data type modifiers are prefixed to the variable name.
Data Type Modifier
Boolean f
Integer i
Long l
String s
Byte b
Single sng
Double dbl
Date/Time dt
Currency cur
Variant vnt

Scope Modifiers

The scope modifiers are used before all other prefixes.
Scope Modifier
Global g
Module m

Miscellaneous Modifiers

Modifier Item
v Variant
This is used with normal data type prefixes to indicate that a variant is being used but a specific data type is expected. For example, in a database application a foreign key might normally be a long (l) but may also be Null, thus the use of a variant. The resulting prefix would be vl.
p Procedure Parameter
This prefix is used to help avoid name collisions when working with local variables and procedure parameters which otherwise share the same name. This modifier is prefixed to the base data type modifier.
rp Return Parameter
Used to indicate output (return values) passed through the parameter list in a procedure. This modifier is prefixed to the base data type modifier.
t User Defined Type
This modifier is used to indicate that the variable is a user-defined data type. It precedes all but the scope modifier.
_a Array
This modifier is appended to the variable name and is used to indicate that the variable is an array.
F - frm Form
The single upper case F is used in form names as specified at design time. The frm tag is used for variables representing forms. For variables, this tag follows the scope modifier.

Control Modifiers

These tags are used in control names and in variables representing controls.
Tag Control Type
chk Check Box
cmd Command Button
cbo Combo Box
dat Data Control
dir Directory List Box
drv Drive List Box
fil File List Box
fra Frame
hsb Horizontal Scroll Bar
img Image
lbl Label
lst List Box
opt Option Button
pnl 3D Panel
pic Picture Box
txt Text Box
tmr Timer
vsb Vertical Scroll Bar
Windows 95 Controls
il Image List
lv List View
sb Status Bar
tb Toolbar
tv Tree View

Data Access Objects

These tags are used with DAO objects and precede all but the scope modifier.
Tag DAO Object
ct Container
db Database
fld Field
grp Group
idx Index
prop Property
qd QueryDef
rs Recordset
rel Relation
td TableDef
usr User
ws Workspace

Given the number of available objects, custom controls, etc., that are available for use in Visual Basic, it would be impossible to come up with a comprehensive list of tags for every type of object. For those not listed (or maybe for those that are as well) you'll need to come up with your own tags. What's more important than using any particular set of tags is to choose a convention for the names and use it consistently. You're sure to be kicking yourself if you go back and look at your code after six months and discover that half of your Byte variables and half of your Boolean variables are prefixed with "b".


Summary

That was a lot to take in, but don't let yourself be confused or intimidated by the number of different modifiers and rules I use in naming objects. Once you get used to using a convention like this it becomes second nature and really does make life easier by allowing you to recognize the nature of the object by merely reading the name.

I'll repeat this again - it doesn't really matter what particular naming convention you choose as long as you name objects consistently. There's enough to learn and do in writing an application without expending excess effort in deciphering poor object names. Using a naming convention will eventually become automatic and that ultimately saves effort because its one less thing to think about.

Note: I have also published a Database Object Naming Conventions page. You might find it helpfull.

Originally written by Joe Garrick