سؤال

تبدو الاستعلامات ذات المعلمات في .Net دائمًا بهذا الشكل في الأمثلة:

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID = @categoryid
", 
   conn);
comm.Parameters.Add("@categoryid", SqlDbType.Int);
comm.Parameters["@categoryid"].Value = CategoryID;

لكنني أصطدم بجدار من الطوب أحاول القيام بما يلي:

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID IN (@categoryids) 
      OR  name LIKE '%@name%'
", 
   conn);
comm.Parameters.Add("@categoryids", SqlDbType.Int);
comm.Parameters["@categoryids"].Value = CategoryIDs;
comm.Parameters.Add("@name", SqlDbType.Int);
comm.Parameters["@name"].Value = Name;

أين

  • معرفات الفئة هي قائمة مفصولة بفواصل من الأرقام "123,456,789" (بدون علامتي الاقتباس)
  • الاسم عبارة عن سلسلة، ربما تحتوي على علامات اقتباس مفردة وأحرف سيئة أخرى

ما هو بناء الجملة الصحيح لهذا؟

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

المحلول

لنفترض أن لديك معرفات الفئات الخاصة بك في مصفوفة أعداد صحيحة وأن الاسم عبارة عن سلسلة.الحيلة هي إنشاء نص الأمر للسماح لك بإدخال كافة معرفات الفئات الخاصة بك كمعلمات فردية وإنشاء مطابقة غامضة للاسم.للقيام بالأمر الأول، نستخدم حلقة لإنشاء سلسلة من أسماء المعلمات @p0 حتى @pN-1 حيث N هو عدد معرفات الفئات في المصفوفة.ثم نقوم بإنشاء معلمة وإضافتها إلى الأمر بمعرف الفئة المرتبط بها كقيمة لكل معلمة مسماة.ثم نستخدم التسلسل على الاسم في الاستعلام نفسه للسماح بالبحث الغامض عن الاسم.

string Name = "someone";
int[] categoryIDs = new int[] { 238, 1138, 1615, 1616, 1617,
                                1618, 1619, 1620, 1951, 1952,
                                1953, 1954, 1955, 1972, 2022 };

SqlCommand comm = conn.CreateCommand();

string[] parameters = new string[categoryIDs.Length];
for(int i=0;i<categoryIDs.Length;i++)
{
   parameters[i] = "@p"+i;
   comm.Parameters.AddWithValue(parameters[i], categoryIDs[i]);
}
comm.Parameters.AddWithValue("@name",$"%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";

هذا استعلام ذو معلمات كاملة من شأنه أن يجعل DBA الخاص بك سعيدًا.أظن أنه نظرًا لأن هذه أعداد صحيحة، على الرغم من أنه لن يكون هناك خطر كبير على الأمان فقط لإنشاء نص الأمر مباشرةً باستخدام القيم، مع الاستمرار في تحديد معلمات الاسم.إذا كانت معرفات الفئات الخاصة بك موجودة في مصفوفة سلسلة، فما عليك سوى تقسيم المصفوفة بفواصل، وتحويل كل منها إلى عدد صحيح، وتخزينها في مصفوفة الأعداد الصحيحة.

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

الفكرة الأصلية من http://www.tek-tips.com/viewthread.cfm?qid=1502614&page=9

نصائح أخرى

أنت بحاجة إلى "%" في قيمة معلمة SQL.

SqlCommand comm = new SqlCommand("SELECT * FROM Products WHERE Category_ID IN (@categoryid1, @categoryid2) OR name LIKE @name", conn);
comm.Parameters.Add("@categoryid1", SqlDbType.Int);
comm.Parameters["@categoryid1"].Value = CategoryID[0];
comm.Parameters.Add("@categoryid2", SqlDbType.Int);
comm.Parameters["@categoryid2"].Value = CategoryID[1];
comm.Parameters.Add("@name", SqlDbType.Int);
comm.Parameters["@name"].Value = "%" + Name + "%";

وهذا النهج لن ينجح.فترة.

تتوقع جملة IN قائمة من المعلمات نفسها، لذلك عند الربط واحد المعلمة لذلك، لديك فرصة لتمريرها واحد قيمة.

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

لست متأكدًا مما إذا كانت هذه هي الطريقة الصحيحة ولكنها طريقة قمت بها من قبل

قائمة templist = قائمة جديدة

comm.Parameters.Add("@categoryids", SqlDbType.varchar);comm.Parameters["@categoryids"].value = string.join("،,templist.toarray())

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