2009-01-20 13 views
9

J'interroge des données à partir de vues susceptibles d'être modifiées. J'ai besoin de savoir si la colonne existe avant que je fasse un crs.get******(). J'ai trouvé que je peux interroger les métadonnées comme ceci pour voir si une colonne existe avant que je demande les données de lui.Comment vérifier si un nom de colonne existe dans un CachedRowSet?

ResultSetMetaData meta = crs.getMetaData(); 
int numCol = meta.getColumnCount(); 

for (int i = 1; i < numCol+1; i++) 
    if(meta.getColumnName(i).equals("name")) 
     return true; 

Existe-t-il un moyen plus simple de vérifier si une colonne existe?

EDIT: Il doit s'agir d'une base de données agnostique. C'est pourquoi je référence le CachedRowSet au lieu de la base de données.

Répondre

8

Il n'y a pas une façon plus simple avec l'API JDBC générale (au moins pas que je sache, ou peux trouver ... J'ai exactement le même code dans mon jeu d'outils cultivés sur place.)

(votre code est pas terminé):

ResultSetMetaData meta = crs.getMetaData(); 
int numCol = meta.getColumnCount(); 

for (int i = 1; i < numCol+1; i++) 
{ 
    if(meta.getColumnName(i).equals("name")) 
    {return true;} 

} 
return false; 

Cela dit, si vous utilisez des API propriétaires, spécifiques à la base de données et/ou des requêtes SQL, je suis sûr que vous pouvez trouver des façons plus élégantes de faire la même chose. ..mais vous devrez écrire du code personnalisé pour chaque base de données que vous devez traiter. Je resterais avec les API JDBC, si j'étais vous.

Y a-t-il quelque chose dans votre proposition de solution qui vous fait penser que c'est incorrect? Cela me semble assez simple ...

+0

Je suis nouveau à cachedRowSet, j'ai juste compris cela pendant que j'écrivais ma question. Poser la question de manière cohérente m'a fait penser différemment. Je fais juste en sorte de rester sur la bonne voie. – WolfmanDragon

+0

Si vous devez rechercher un grand nombre de colonnes, vous pouvez toujours avoir ce retour un 'Set 'rempli par les appels de méthode' getColumnName (i) '. De cette façon, vous pouvez vous référer à 'set.contains (myCol)' au lieu d'itérer tout cela. – corsiKa

1

Quelle base de données?

Je pense que dans Oracle il y a des tables où les colonnes sont listées.

Je ne me souviens pas si cela fonctionne pour une vue aussi, mais je suppose qu'ils le font, ce fut quelque chose comme:

select colum_name from all_views where view_name like 'myview' 

ou

select name from all_objects where object_name like 'myview' and object_type='view' 

Je ne me souviens pas exactement de la syntaxe . Vous devriez avoir des permissions spatiales cependant.

Chaque SGBDR devrait avoir quelque chose de similaire.

Vous pouvez également effectuer la requête

select * from myView where 1 = 0 ; 

Et à partir des métadonnées obtenir les colonnes, si ce que vous voulez éviter la récupération des données avant de savoir si les colonnes sont présentes.

+0

Il doit s'agir d'une base de données agnostique. Je n'ai jamais travaillé avec Oracle, mais je le ferai peut-être très bientôt. +1 pour de bonnes informations sur les vues Oracle. – WolfmanDragon

+0

Puis sélectionnez * dans myview où 1 = 0 devrait faire. Travailler avec RsMd mais c'est assez rapide. – OscarRyz

1

Non, il n'y a vraiment pas de meilleur moyen. Vous voudrez peut-être relooker le problème. Si vous pouvez redéfinir le problème, cela rend parfois la solution plus simple car le problème a changé.

0

AVERTISSEMENT: commentaire suivant uniquement de la mémoire sans documents de soutien :)

Si je me souviens bien il y a un problème mystérieux qui se cabre son toujours aussi laid tête quand l'oracle cache la mise en œuvre de rowset est utilisé avec la connexion mise en commun. Il semble y avoir une référence silencieuse à la connexion contenue dans l'objet rowset mis en cache (même s'il est supposé être déconnecté), ce qui ferme une autre connexion ouverte ultérieurement à partir du pool lors de la récupération de place. Pour cette raison, j'ai finalement abandonné et écrit mon propre calque d'objet de données (ces jours-ci je remettrais ça au printemps & hibernate).

7

Vous pouvez prendre l'approche la plus courte en utilisant le fait que findColumn() lancera une SQLException pour InvalidColumName si la colonne n'est pas dans CachedRowSet.

par exemple

try { 
    int foundColIndex = results.findColumn("nameOfColumn"); 
} catch { 
    // do whatever else makes sense 
} 

probablement un abus de traitement des exceptions (par EffectiveJava 2nd ed article 57), mais il est une alternative à une boucle à travers toutes les colonnes des méta-données.

+0

Cela ne semble pas être une bonne idée. – Khatri