سؤال

أنا مشغول على قطعة من التعليمات البرمجية للحصول على alle أسماء الأعمدة من جدول من قاعدة بيانات Oracle.رمز خطرت لي تبدو مثل هذا:

DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection(
  "jdbc:oracle:thin:@<server>:1521:<sid>", <username>, <password>);

DatabaseMetaData meta = conn.getMetaData();
ResultSet columns = meta.getColumns(null, null, "EMPLOYEES", null);
int i = 1;
while (columns.next())
{
  System.out.printf("%d: %s (%d)\n", i++, columns.getString("COLUMN_NAME"), 
    columns.getInt("ORDINAL_POSITION"));
}

عندما ركضت هذا الرمز إلى دهشتي أيضا العديد من الأعمدة التي تم إرجاعها.نظرة فاحصة تكشف أن ResultSet الواردة مكررة مجموعة من الأعمدة ، أيكل عمود أعيدت مرتين.هنا هو الإخراج حصلت على:

1: ID (1)
2: NAME (2)
3: CITY (3)
4: ID (1)
5: NAME (2)
6: CITY (3)

عندما أنظر الجدول باستخدام SQL Oracle Developer يظهر هذا الجدول فقط ثلاثة أعمدة (ID, NAME, CITY).لقد جربت هذا الكود ضد عدة جداول في قاعدة البيانات الخاصة بي وبعض تعمل على ما يرام ، بينما يحمل هذا غريب السلوك.

يمكن أن يكون هناك خلل في أوراكل JDBC السائق ؟ أو أفعل شيئا خطأ هنا ؟


تحديث: شكرا Kenster لدي الآن طريقة بديلة استرداد أسماء الأعمدة.يمكنك الحصول عليها من ResultSet, مثل هذا:

DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@<server>:1521:<sid>", <username>, <password>);

Statement st = conn.createStatement();
ResultSet rset = st.executeQuery("SELECT * FROM \"EMPLOYEES\"");
ResultSetMetaData md = rset.getMetaData();
for (int i=1; i<=md.getColumnCount(); i++)
{
    System.out.println(md.getColumnLabel(i));
}

ويبدو أن تعمل على ما يرام و لا التكرارات عاد!وبالنسبة لأولئك الذين يتساءلون:وفقا هذا بلوق يجب عليك استخدام getColumnLabel() بدلا من getColumnName().

هل كانت مفيدة؟

المحلول

في أوراكل ، Connection.getMetaData() إرجاع البيانات الفوقية لهذا كامل قاعدة البيانات ليست مجرد مخطط كنت يحدث أن تكون متصلا.وذلك عند العرض null أول اثنين من الحجج meta.getColumns(), أنت لا تصفية النتائج فقط المخطط.

تحتاج إلى توفير اسم أوراكل المخطط إلى أحد من الأولين المعلمات meta.getColumns(), ربما ثانية واحدة, على سبيل المثال

meta.getColumns(null, "myuser", "EMPLOYEES", null);

انها قليلا مزعجة الاضطرار إلى القيام بذلك ، لكن هذا الطريق أوراكل الناس اختاروا تنفيذ برنامج تشغيل JDBC.

نصائح أخرى

هذا لا تجب مباشرة على سؤالك ولكن وثمة نهج آخر هو تنفيذ الاستعلام:

select * from tablename where 1 = 0

هذا سيعود ResultSet ، حتى على الرغم من أنه لا تحديد أي الصفوف.مجموعة النتائج الوصفية سوف تتطابق مع الجدول الذي قمت بتحديده من.اعتمادا على ما تفعله هذا يمكن أن يكون أكثر ملاءمة. tablename يمكن أن يكون أي شيء يمكنك تحديد على--لم يكن لديك للحصول على القضية الصحيح أو تقلق بشأن ما مخطط انها في.

في التحديث على سؤالك لقد لاحظت أنك غاب واحد جزء رئيسي من Kenster الجواب.لقد حددت 'حيث' الشرط 'حيث 1 = 0' التي لم يكن لديك.هذا مهم جدا لأنه إذا ترك الأمر ثم أوراكل سوف نحاول العودة الجدول بأكمله.و إذا كنت لا سحب كافة السجلات على أوراكل سوف تعقد لهم في انتظار لك صفحة من خلالها.مضيفا أن شرط حيث لا تزال يعطيك الفوقية ، ولكن من دون أي من النفقات العامة.

أيضا, وأنا شخصيا استخدام 'where rownum < 1', منذ أوراكل يعرف على الفور أن جميع rownums الماضي ، وأنا لست متأكدا إذا كان ذكيا بما فيه الكفاية محاولة اختبار كل من سجل '1 = 0'.

بالإضافة إلى skaffman الجواب -

استخدم الاستعلام التالي في أوراكل:

select sys_context( 'userenv', 'current_schema' ) from dual;  

للوصول إلى المخطط الحالي اسم إذا كنت مقيدة بذلك في جاوة.

هذا هو السلوك بتكليف من JDBC API - تمرير القيم الخالية الأولى والثانية معلمة getColumns يعني أنه لا الكتالوج اسم ولا اسم المخطط تستخدم لتضييق نطاق البحث.رابط الوثائق .صحيح أن بعض JDBC مختلفة السلوك بشكل افتراضي (هـ.ز الخلية ConnectorJ افتراضيا يقيد الحالي كتالوج), ولكن ليس هذا هو المعيار ، و موثقة على هذا النحو

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top