سؤال

أحاول الدخول في تفاصيل PDO.لذلك قمت بترميز هذا:

$cn = getConnection();

// get table sequence
$comando = "call p_generate_seq('bitacora')";
$id = getValue($cn, $comando);

//$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (?, ?, ?)';
$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (:id, :estado, :fch_creacion)';
$parametros = array (
    ':id'=> (int)$id,
    ':estado'=>1,
    ':fch_creacion'=>date('Y-m-d H:i:s')
);
execWithParameters($cn, $comando, $parametros);

تعمل وظيفة getValue الخاصة بي بشكل جيد، وأحصل على التسلسل التالي للجدول.ولكن عندما أدخل إلى execWithParameters، أحصل على هذا الاستثناء:

استثناء شركة تنمية نفط عمان:حالة SQL[HY000]:خطأ عام:2014 لا يمكن تنفيذ الاستعلامات بينما تكون الاستعلامات الأخرى غير المخزنة نشطة.فكر في استخدام PDOStatement::fetchAll().وبدلاً من ذلك، إذا كان الكود الخاص بك سيتم تشغيله فقط على mysql، فيمكنك تمكين التخزين المؤقت للاستعلام عن طريق تعيين السمة PDO::MYSQL_ATTR_USE_BUFFERED_QUERY.في D:\Servidor\xampp_1_7_1\htdocs\bitacora\func_db.php على السطر 77

حاولت تعديل سمات الاتصال لكنها لا تعمل.

هذه هي وظائف قاعدة البيانات الأساسية الخاصة بي:

function getConnection() {
    try {
        $cn = new PDO("mysql:host=$host;dbname=$bd", $usuario, $clave, array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            ));

        $cn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
        return $cn;
    } catch (PDOException $e) {
        print "Error!: " . $e->getMessage() . "<br/>";
        die();
    }
}
function getValue($cn, $comando) {
    $resul = $cn->query($comando);
        if (!$resul) return null;
        while($res = $resul->fetch()) {
            $retorno = $res[0][0];
            break;
        }
        return $retorno;
}
function execWithParameters($cn, $comando, $parametros) {
    $q = $cn->prepare($comando);
    $q->execute($parametros);
    if ($q->errorInfo() != null) {
        $e = $q->errorInfo();
        echo $e[0].':'.$e[1].':'.$e[2];
    }
}

هل يستطيع أحد أن يلقي الضوء على هذا؟بي دي.من فضلك لا تقترح عمل معرف رقمي ذاتي، لأنني أقوم بالترقية من نظام آخر.

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

المحلول

والمسألة هي أن الخلية يسمح فقط لمؤشر المتميز واحدة في وقت معين. باستخدام طريقة جلب ()، وليس مضيعة للجميع البيانات المعلقة، فإنك تكون قد غادرت مؤشر مفتوحة.

والنهج الموصى به هو أن تستهلك جميع البيانات باستخدام طريقة fetchAll (). وبديل ذلك هو استخدام الأسلوب closeCursor ().

إذا قمت بتغيير هذه الوظيفة، أعتقد أنك سوف تكون أكثر سعادة:

<?php
function getValue($cn, $comando) {
    $resul = $cn->query($comando);
    if (!$resul) return null;
    foreach ($resul->fetchAll() as $res) {
            $retorno = $res[0];
            break;
    }
    return $retorno;
}
?>

نصائح أخرى

وأنا لا أعتقد أن PDOStatement :: closeCursor () تعمل إذا كنت لا تفعل استعلام يقوم بإرجاع البيانات (أي على UPDATE، INSERT، الخ).

والحل الأفضل هو ببساطة إلغاء تعيين () الكائن PDOStatement بك بعد استدعاء PDOStatement :: تنفيذ ():

$stmt = $pdo->prepare('UPDATE users SET active = 1');
$stmt->execute();
unset($stmt);

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

وربما getValue يمكن ان تكون ثابتة عن طريق إضافة

$resul->closeCursor();

وقبل العودة.

وإلا، إذا الاستعلامات لgetValue سوف دوما بإرجاع قيمة واحدة (أو بعض بما فيه الكفاية)، ويبدو أن استخدام سوف يفضل fetchAll.

لقد أمضيت 15 دقيقة فقط في البحث على Google في جميع أنحاء الإنترنت، واطلعت على ما لا يقل عن 5 أسئلة مختلفة حول Stackoverflow، وبعضهم ادعى أن الخطأ الخاص بي نشأ على ما يبدو من الإصدار الخاطئ من PHP، أو الإصدار الخاطئ من مكتبة MySQL أو أي أشياء أخرى سحرية من الصندوق الأسود...

لقد قمت بتغيير كل التعليمات البرمجية الخاصة بي إلى استخدام "fetchAll" وقمت حتى باستدعاء CloseCursor() وunset() على كائن الاستعلام بعد كل استعلام.لقد كنت بصراحة أشعر باليأس!لقد قمت أيضًا بتجربة علامة MYSQL_ATTR_USE_BUFFERED_QUERY، لكنها لم تنجح.

أخيراً رميت كل شيء من النافذة ونظرت إلى خطأ PHP، وتتبعت سطر التعليمات البرمجية حيث حدث ذلك.

SELECT AVG((original_bytes-new_bytes)/original_bytes) as saving 
    FROM (SELECT original_bytes, new_bytes FROM jobs ORDER BY id DESC LIMIT 100) AS t1

على أية حال، حدثت المشكلة بسبب جهازي original_bytes و new_bytes كلاهما حيث تكون Bigints غير موقعة، وهذا يعني أنه إذا كان لدي وظيفة حيث تكون وحدات البايت الجديدة أكبر في الواقع من وحدات البايت الأصلية، فسوف أواجه خطأ MySQL "خارج النطاق" السيئ.وقد حدث ذلك بشكل عشوائي بعد تشغيل خدمة التصغير الخاصة بي لفترة قصيرة.

لماذا بحق الجحيم حصلت على هذا الخطأ الغريب في MySQL بدلاً من مجرد إعطائي الخطأ البسيط، وهو أمر خارج عن إرادتي!لقد ظهر بالفعل في SQLBuddy (PHPMyAdmin خفيف الوزن) عندما قمت بتشغيل الاستعلام الأولي.لقد كانت لدي استثناءات PDO قيد التشغيل، لذا كان من المفترض أن يكون ذلك قد أعطاني خطأ MySQL.

لا يهم، خلاصة القول هي:

إذا حدث لك هذا الخطأ، فتأكد من أن MySQL الخام الخاص بك صحيح بالفعل وأنه لا يزال يعمل!!!

وكان صديق لي كثيرا من نفس المشكلة مع XAMPP 1.7.1 بناء. بعد استبدال XAMPP / فب / * قبل php.net بناء و5.2.9-2 نسخ جميع الملفات اللازمة لXAMPP / اباتشي / بن انها عملت بشكل جيد.

إذا كنت تستخدم XAMPP 1.7.1، تحتاج فقط للترقية إلى 1.7.2.

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