سؤال

تم تجميع العميل مع OCI: 10.2.0.4.0
الخادم: إصدار Oracle9i Enterprise Edition 9.2.0.4.0

الاستعلام الإشكالي هو:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = '05-JUL-08'

وصف الجدول:

SQL>describe LOG;

TEL NOT NULL VARCHAR2(15)
CODIGO NOT NULL VARCHAR2(20)
DATE_PROC NOT NULL DATE

على الرغم من أن الأمر قد يبدو بسيطًا ، عند تنفيذه مباشرة على الخادم باستخدام SQLPlus ، فإنه يعيد نتيجة ، ولكن عند تنفيذه من التطبيق الذي يستخدم OCI ، يعود هذا الاستعلام OCI_NO_DATA دائماً. في البداية ، كانت قيمة التاريخ أيضًا عنصرًا نائبًا ، لكنني اكتشفت أنه حتى إعطاء حرفي مثل '05-JUL-08' لم ينجح. لقد جربت ما يلي:

  • لقد جربت الأساسيات: الاستعلام عن DB من العميل يعمل. هذا هو الذي يعطيني المتاعب
  • ما يلي يعمل:

    SELECT CODIGO FROM LOG WHERE TEL = :telnumber
    
  • التنفيذ ALTER SESSION SET NLS_DATE_FORMAT="DD-MM-YYYY"; قبل الاستعلام في كل من الخادم والعميل. نفس النتيجة: يقوم الخادم بإرجاع البيانات ، العميل OCI_NO_DATA

  • حاول التغيير DATE_PROC شكل ، يجمع هذا مع استخدام TO_DATE(). نفس النتيجة.
  • بحثت ، بحثت ، بحث. لا اجابة

أنا يائسة بعض الشيء للعثور على إجابة ، وسأقدر أي مساعدة ويمكنني تقديم أكبر عدد ممكن من التفاصيل حسب الحاجة. شكرًا.

--- مزيد من المعلومات ---

update log set DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS') where CODIGO='BancoOne';

لقد جربت مجموعات مختلفة باستخدام Trunc () و "Set Set Set Set NLS_Date_Format" ... وهذا ما أحصل عليه:

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

في الخادم: إرجاع: "Bancoone" (قيمة جيدة)
في تطبيق OCI: إرجاع OCI_NO_DATA

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

في الخادم: إرجاع: "Bancoone"
في تطبيق OCI: إرجاع "Bancoone"

لذا فإن النقطة هي ، لماذا يعطي تطبيق OCI نتائج مختلفة إذا كان كلاهما يصل إلى نفس خادم DB؟

أيضًا ، لتوضيح الغرض من تطبيق OCI: يحتوي على استعلام ليتم تكوينه من قبل المستخدم. الفكرة هي أن المستخدم سيؤدي إلى تكييف الاستعلام حسب الرغبة في ملاءمة حقل التاريخ الموجود في Desty DB ، ولهذا السبب يجب ألا أتضمن عبارات "ALTER SETATE SET NLS_DATE_FORMAT" في الكود الخاص بي ، حيث لن أعرف تنسيق التاريخ. وبهذه الطريقة ، أريد توفير المرونة للمستخدم ، ولا تعتمد على تنسيقات تاريخ محددة. هل لهذا معنى؟ أي اقتراحات؟

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

المحلول

عمودك Date_proc هو تاريخ ، يجب عليك دائماً قارنه بتاريخ و مطلقا الاعتماد على تحويل البيانات الضمني.

جرب هذا:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = DATE '2008-07-05'

أو هذا:

SELECT CODIGO 
  FROM LOG 
 WHERE TEL = :telnumber 
   AND DATE_PROC = to_date('05-JUL-08', 'DD-MON-RR')

إذا استطعت ، الامتناع عن استخدام تنسيق التاريخ في الكود الخاص بك يستخدم الحروف لعدة أشهر (لأن الرمز سوف تفشل عندما تقوم بتغيير اللغة الافتراضية) واثنين فقط من chars لسنوات (غموض القرن). أحب الاستخدام 'YYYY/MM/RR' لأنه سيتم فرز هذا التنسيق كتاريخ أصلي.

نصائح أخرى

كيف تم إدخال السجلات؟

تقوم حقول التاريخ بتخزين معلومات الوقت ، وبالتالي عند إدخال السجلات باستخدام SYSDATE ، سيحتوي حقل التاريخ على "قيم" مختلفة للسجلات خلال ذلك اليوم. عندما تقوم بتنفيذ Date_proc = '05 -jul-08 '، فأنت تقول أين تساوي Date_Proc بالضبط 5 يوليو 2008 في الساعة 12:01:00. إذا قمت بإدخال السجل في الساعة 12:01 مع Sysdate ، فلن يتم إرجاعه. هل حاولت استخدام A بين أو trunc؟

هنا مثال:

drop table test_date;
create table test_date (id number, ud date);

insert into test_date values (1, '15-jan-10');
insert into test_date values (2, '15-jan-10');
insert into test_date values (3, '15-jan-10');
insert into test_date values (6, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (7, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (8, '16-jan-10');
commit;

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where ud = '15-jan-10';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00      

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where trunc(ud) = '15-jan-2010';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
6                      15-JAN-10                 15-JAN-2010 08:01:55                                                        
7                      15-JAN-10                 15-JAN-2010 08:01:55

أود أن أقول أنك تطرح السؤال الخطأ.

يعتمد Oracle على مشاركة SQL للأداء ، وعندما تلتزم بسلسلة ، مثل "20080705" ، لا يمكن مشاركة SQL. تفاصيل هنا.

لذلك يجب أن تكون قيمة البيانات عنصرًا نائبًا ويجب أن تكون من نوع البيانات الصحيح (التاريخ). المثال هنا يجب أن يساعد في القيام بذلك.

ومع ذلك ، إذا كان هذا يعمل

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

لكن هذا لا

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 
AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

سأحاول

SELECT TO_CHAR(DATE_PROC,'DD-MM-YYYY HH24:MI:SS') FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

كان لدينا هذا الخطأ فقط (OCI_NO_DATA) بسبب شخص يغير ساعة اليوم على جهاز الكمبيوتر الخاص به. عندما يعيدون التاريخ/الوقت إلى الوقت المناسب ، بدأ التطبيق يعمل بشكل جيد.

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