Solved

rs.getString() -> Invalid Descriptor Index Error

Posted on 2000-05-09
8
788 Views
Last Modified: 2008-02-01
I am using the jdbc:odbc driver to access a SQL Server table in my applet.  It seems to be working fine except on 2 fields I get an error (Invalid Descriptor Index) when calling the getString() method of the resultset.  Any suggestions on how to resolve this?


CODE:

Statement inetStatement = connInetDB.createStatement();

ResultSet rs= inetStatement.executeQuery("SELECT * FROM tblTable");                  
sUID = rs.getString("UID");
0
Comment
Question by:jsimoni
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
  • +2
8 Comments
 
LVL 7

Expert Comment

by:Ravindra76
ID: 2793948
Post full code
0
 

Expert Comment

by:j_murray
ID: 2794178
Is this line:

sUID = rs.getString("UID");

exactly as written, does it look like this:

sUID = rs.getString(5);

If it looks like the second line, then you may be looking for a column index that does not exist. If it looks like the first, then it looks like the column name that you requested is not there.

Try this code to debug:

ResultSetMetaData rsmd = rs.getMetaData();
for (int i=0;i<rsmd.getColumnCount();i++)
{
    System.out.println("Column # " + i + " is " + rsmd.getColumnName());
}

You can then compare the column name printed out in the debug code to the ones you have in you rs.getString() calls.

 
0
 
LVL 1

Author Comment

by:jsimoni
ID: 2794333
i am using

sUID = rs.getString("UID");

and this field is in my recordset.

0
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 

Expert Comment

by:j_murray
ID: 2794359
Did you check the ResultSetMetaData column names? The strings are case sensitive.
0
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 100 total points
ID: 2795447
I don't have my JDBC reference at hand so I can't be completely sure, but I think your problem is that you used the query form "SELECT *" which does not explictly name the columns in the result set. Note that the JDK documentation contains this paragraph in the ResultSet class description:

"Column names used as input to getXXX methods are case insensitive. When a getXXX method is called with a column name and several columns have the same name, the value of the first matching column will be returned. The column name option is designed to be used when column names are used in the SQL query that generated the result set. For columns that are NOT explicitly named in the query, it is best to use column numbers. If column names are used, there is no way for the programmer to guarantee that they actually refer to the intended columns."

Additionally, the JDBC 1.2 Specification contains the 'footnote':

"Note that certain SQL queries can return tables without column names or with multiple identical column names. In these cases, programmers should use column numbers."

As I said, I don't have my JDBC book handy. But I do seem to remember coming across statements that indicate a "SELECT *" is one of these cases.

Of course, using "SELECT *" is not a recommended practice for programmatic SQL. It has been traditionally held that doing so makes the application dependent on the order in which columns were defined in the CREATE TABLE statement (as that is usually the order the database engine will return column values) as well as making the program sensitive to other changes in the table structure. Even if you argue less sensitivity to column ordering because the API retrieves individual column values, the recommendation in the JDBC documentation is to read column values from left to right in the order specified in the query and to read each column value only once.

I would recommend changing either a) using the getXXX(int index) method calls or b) changing the SELECT statement to explictly name the column in the result set.

Best regards,
Jim Cakalic
0
 

Expert Comment

by:diegojimenez
ID: 2795881
Hello, jsimoni. I had a simillar case, and you must do this.
1.-ResultSet rs= inetStatement.executeQuery("SELECT * FROM tblTable");
2.-ResultSetMetaData    metaData = null;
metaData = rs.getMetaData();
This is to get the number of colums and theirs names.
3.- for example for obtains all the columns:
int_numCol = metaData.getColumnCount();
4.-Imagine that all the rows of the query will be stored in a vector() (one for row) called fila (Vector fila = new Vector())
for (int i=0;i<int_numCol;i++){
fila.addElement((String) rs.getString(metaData.getColumnLabel(int_i+1)));

5.- Now you have in the vector fila one row from the query.

You must use the Metadata from the resulset because the strings are case sensitive.
Good Luck!

0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2796094
ResultSetMetaData is typically used in situations where a ResultSet has been generated but the object processing the ResultSet that doesn't necessarily know the contents. That object then needs to interrogate the ResultSet to gather information. ResultSetMetaData also contains additional information which cannot be intuited from the ResultSet itself such as column display size, display label, size and precision, etc.

In this case, unless I missed something about your problem, I don't think it is necessary to make the problem that complex. Your program prepared an SQL statement, executed it, and now holds a ResultSet from which you want the column values. You know when you write the program specifically which columns you want from the table. If all you need from the metadata is the names of the columns, then my suggestion remains to either specify the columns in the select statement instead of using '*' and use the getXXX(String name) methods or use the getXXX(int index) methods. Otherwise, your application will be performing unnecessary work by interrogating the ResultSetMetaData for each column by index just to get the name so that you can then interrogate the ResultSet by column name. If you need that flexibility -- great, go for it. If not, ...

BTW, to add to my statements in the previous post about not using "SELECT *" in programmatic SQL, I'll add that it has the potential to adversely impact performance. If the table being queried has, say, 10 columns, and you only need half of them in a specific application, retrieving all the columns is unnecessary overhead requiring additional work on the part of the database engine, additional transmission time to push the results from the database to your application, additional time extracting the values from the ResultSet in your application, and additional memory resources at each stage. Add to that the coupling and dependency issues I mentioned previously and you get a flavor for why we discourage using "SELECT *" in a program. Use it freely when querying the database by hand. I hate typing column names unless I absolutely must. But take more care in your code where you will be typing the names just once.

Best regards,
Jim Cakalic
0
 
LVL 1

Author Comment

by:jsimoni
ID: 2796304
i had tried .findColumn() to get the index of the column and .getString() using that index.  the .findColumn() worked and returned a valid index, but the .getString() still failed.

i usually don't use "SELECT *", but in this case i want to pull back all of the columns.  but by changing it to specify all the column names in my select statement it did work.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question