قم بإنشاء مشغل Oracle DB باستخدام برنامج تشغيل JDBC رفيع

StackOverflow https://stackoverflow.com/questions/4107028

سؤال

حاليا أقوم بإعداد بيئة اختبار للتطبيق. أنا أستخدم Junit و Spring في بيئة الاختبار الخاصة بي. قبل تنفيذ الاختبار ، أريد إعداد حالة بيئة اختبار قاعدة البيانات. لقد كتبت بالفعل البرامج النصية SQL (المخطط والبيانات) وهي تعمل بشكل جيد في Oracles SQLDeveloper. عندما حاولت تنفيذها باستخدام برنامج تشغيل Oracle Thin JDBC ، فشل التنفيذ. يبدو أن السائق الرقيق لا يحب إنشاء عبارات الزناد.

قرأت أنه يجب علي استخدام برنامج تشغيل OCI بدلاً من برنامج تشغيل رفيع. تكمن مشكلة برنامج تشغيل OCI في أنه ليس مستقلاً من النظام الأساسي ويستغرق الأمر وقتًا لإعداده.

مثال على الكود الخاص بي:

CREATE TABLE "USER"
  (
    USER_ID          NUMBER(10) NOT NULL,
    CREATOR_USER_FK  NUMBER(10) NOT NULL,
    ...
    PRIMARY KEY (USER_ID)
  );
CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1;
CREATE TRIGGER "USER_ID_SEQ_INC" BEFORE
  INSERT ON "USER" FOR EACH ROW BEGIN
  SELECT SEQ_USER.nextval
  INTO :new.USER_ID
  FROM DUAL;
END;

إذا قمت بتنفيذ عبارة المشغل ، فإن التنفيذ يفشل ، لكنني يبدو أن الجزء الأول من الاستعلام (إنشاء مشغل "user_id_seq_inc" ... "مستخدم" ... يبدأ ... من مزدوج ؛) بنجاح ، ولكن يبدو أن الزناد فاسد إذا حاولت استخدامه. يأتي خطأ فشل التنفيذ مع الجزء الثاني من نهاية البيان ؛ "ORA-00900: بيان SQL غير صالح".

هل يعرف أحد حلًا لهذه المشكلة؟ أرغب فقط في إنشاء مشغل مع برنامج تشغيل JDBC Thin JDBC مستقل.

هتافات!

كيفن

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

المحلول

شكراً يا رفاق على إجاباتك ، إنه يعمل بشكل جيد الآن. كان السبب هو خطأ بناء الجملة أو تفسير ملف رمز SQL الخاص بي مع Spring FrameFork. عندما أقوم بتنفيذ العبارات مباشرة باستخدام طريقة تنفيذ JDBC ، فإنه يعمل ، عندما أستخدم وظيفة الربيع لتنفيذ البرنامج النصي. باستخدام رمز Oracle SQL ، يبدو الأمر صعبًا ، لأنه إذا استخدمت رمز HSQLDB SQL ، فإنه يعمل بشكل جيد.

اختبار condext.xml:

...
<jdbc:initialize-database data-source="dataSource"
    ignore-failures="DROPS" enabled="${jdbc.enableSqlScripts}">
    <jdbc:script location="${jdbc.initLocation}" />
    <jdbc:script location="${jdbc.dataLocation}" />
</jdbc:initialize-database>
...

Schema.Sql:

DROP SEQUENCE SEQ_USER;
DROP TABLE "USER" CASCADE CONSTRAINTS;
PURGE TABLE "USER";
CREATE TABLE "USER"
  (
    USER_ID          NUMBER(10) NOT NULL,
    CREATOR_USER_FK  NUMBER(10) NOT NULL,
    PRIMARY KEY (USER_ID)
  );
ALTER TABLE "USER" ADD CONSTRAINT FK_USER_CUSER FOREIGN KEY (CREATOR_USER_FK) REFERENCES "USER" (USER_ID);
CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1;
CREATE TRIGGER "USER_ID_SEQ_INC" BEFORE
  INSERT ON "USER" FOR EACH ROW
  WHEN (new.USER_ID IS NULL)
BEGIN
  SELECT SEQ_USER.nextval
  INTO :new.USER_ID
  FROM DUAL;
END;
/
ALTER TRIGGER "USER_ID_SEQ_INC" ENABLE;

هذا يعمل بشكل جيد! من المهم إزالته ; في نهاية البيانات ، يستثني بيان الزناد !!!

@Before
public void executeSomeSql() {
    Connection c;
    try {
        c = dataSource.getConnection();
        c.createStatement()
                .execute("CREATE TABLE \"USER\" (USER_ID NUMBER(10) NOT NULL, CREATOR_USER_FK NUMBER(10) NOT NULL, PRIMARY KEY (USER_ID))");
        c.createStatement()
                .execute("CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1");
        c.createStatement()
                .execute("CREATE OR REPLACE TRIGGER \"USER_ID_SEQ_INC\" BEFORE INSERT ON \"USER\" FOR EACH ROW WHEN (new.USER_ID IS NULL) BEGIN SELECT SEQ_USER.nextval INTO :new.USER_ID FROM DUAL; END;");
    } catch (SQLException e) {
        logger.debug(e);
    }
}

نصائح أخرى

إنشاء المشغلات يعمل مع أي نوع من برنامج تشغيل JDBC ؛ يجب أن يكون هناك شيء خاطئ في بناء جملة SQL - وهو أمر غريب لأن Oracle يجب أن يبلغ أنه عند تشغيل CREATE TRIGGER (ليس عندما تستخدمه في المرة الأولى).

منذ أن استخدمت BEGIN ... END; تأكد من أن لديك حقا ; بعد، بعدما END في SQL الذي ترسله إلى DB.

إذا لم يكن هذا هو السبب ، تحقق من هذه المقالة.

أعلم أن هذا منشور قديم ولكن ها هو إجابتي.

بشكل افتراضي ، تقسيم تعليمات Spring "تهيئة database" البرنامج النصي المحدد باستخدام حرف Semicolon: "؛".

في الزناد ، غالبًا ما يكون هناك فاصلة فاصلة داخل الزناد ، وبالتالي يتم تقسيم الاستعلامات وتنفيذها بشكل سيء.

الحل هو استخدام حرف منقسم آخر ("|" على سبيل المثال) مثل هذا:

<jdbc:initialize-database>
    <jdbc:script location="classpath:myscript.sql" separator="|"/>
</jdbc:initialize-database>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top