كيف أتعامل مع علامات الاقتباس في SQL [نسخة مكررة]

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

  •  09-06-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

لدي قاعدة بيانات بها أسماء مثل John Doe وما إلى ذلك.لسوء الحظ، تحتوي بعض هذه الأسماء على اقتباسات مثل Keiran O'Keefe.الآن عندما أحاول البحث عن هذه الأسماء على النحو التالي:

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

لقد (من المفهوم) الحصول على خطأ.

كيف أمنع حدوث هذا الخطأ.أنا أستخدم Oracle وPLSQL.

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

المحلول

حرف الهروب هو '، لذا ستحتاج إلى استبدال الاقتباس بعلامتي اقتباس.

على سبيل المثال،

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

يصبح

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

ومع ذلك، ربما يكون من غير الصحيح أن تفعل ذلك بنفسك.قد تحتوي لغتك على وظيفة للهروب من السلاسل لاستخدامها في SQL، ولكن الخيار الأفضل هو استخدام المعلمات.عادة ما يعمل هذا على النحو التالي.

سيكون أمر SQL الخاص بك هو:

SELECT * FROM PEOPLE WHERE SURNAME=?

وبعد ذلك، عند تنفيذه، تقوم بتمرير "O'Keefe" كمعلمة.

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

يجب أن أشير أيضًا إلى أنه على الرغم من أن مثالك يتسبب في حدوث خطأ فقط، إلا أنك تعرض نفسك للكثير من المشكلات الأخرى من خلال عدم الهروب من السلاسل بشكل مناسب.يرى http://en.wikipedia.org/wiki/SQL_injection للحصول على نقطة انطلاق جيدة أو الكلاسيكية التالية كوميدي xkcd.

alt text

نصائح أخرى

أوراكل 10 الحل هو

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'

الاستعلامات ذات المعلمات هي صديقتك، كما اقترح مات.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

سوف يحمونك من الصداع المرتبط به

  • سلاسل مع علامات الاقتباس
  • الاستعلام باستخدام التواريخ
  • حقن SQL

استخدام SQL ذو معلمات له فوائد أخرى، فهو يقلل من حمل وحدة المعالجة المركزية (بالإضافة إلى الموارد الأخرى) في Oracle عن طريق تقليل مقدار العمل الذي تتطلبه Oracle لتحليل العبارة.إذا كنت لا تستخدم المعلمات (نسميها متغيرات الربط في Oracle)، فسيتم التعامل مع "select * from foo Where bar='cat'" و"select * from foo Where bar='dog'" كبيانات منفصلة، ​​حيث " حدد * من foo حيث bar=:b1" هو نفس البيان، مما يعني أن أشياء مثل بناء الجملة وصلاحية الكائنات المشار إليها وما إلى ذلك... لا تحتاج إلى التحقق منها مرة أخرى.هناك مشكلات عرضية تنشأ عند استخدام متغيرات الربط والتي تتجلى عادةً في عدم الحصول على خطة تنفيذ SQL الأكثر كفاءة ولكن هناك حلول بديلة لذلك وتعتمد هذه المشكلات حقًا على المسندات التي تستخدمها والفهرسة وانحراف البيانات.

تتم تصفية الإدخال عادةً على مستوى اللغة بدلاً من طبقات قاعدة البيانات.
يحتوي كل من php و.NET على مكتبات خاصة بهم للهروب من عبارات SQL.تحقق من لغتك، وانظر ما هو متاح.
إذا كانت بياناتك موثوقة، فيمكنك فقط إجراء استبدال سلسلة لإضافة "" أخرى أمام "" للهروب منها.عادةً ما يكون هذا كافيًا إذا لم تكن هناك أي مخاطر بأن يكون الإدخال ضارًا.

أفترض أن السؤال الجيد هو ما هي اللغة التي تستخدمها؟
في PHP ستفعل:اختر * من الأشخاص الذين لديهم اللقب='mysql_escape_string(O'Keefe)'
ولكن بما أنك لم تحدد اللغة، فسأقترح عليك البحث في دالة سلسلة الهروب mysql أو غير ذلك بلغتك.

للتعامل مع عروض الأسعار إذا كنت تستخدم Zend Framework، إليك الرمز

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

على سبيل المثال ؛

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''

تم العثور عليه في أقل من 30 عامًا على Google ...

الأسئلة الشائعة حول Oracle SQL

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