Parametrlarni tanlangCommand bo'sh natija beradi

Ayni paytda kodimni biroz tozalamoqchiman va VS menga aytgandek SqlParameter ni sql buyruqlar uchun string aralashmasidan foydalanish yaxshiroq. Shuning uchun kodimni o'zgartirishga qaror qildim, afsuski endi men natijani bilmayman va nima uchun buni bilmayman. Mana mening kodimning qismi:

...    
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection(GetSQLConnectionString());
SqlDataAdapter sqlSelect = new SqlDataAdapter();
try
{
    connection.Open();
    sqlSelect.SelectCommand = connection.CreateCommand();
    sqlSelect.SelectCommand.CommandText = "SELECT id, @FROM AS \"from\", @TO AS \"to\" FROM Dictionary WHERE @FROM LIKE @SEARCHSTRING";
    sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@FROM", this.from));
    sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@TO", this.to));
    sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@SEARCHSTRING", "'%" + this.SearchField.Text + "%'"));

    sqlSelect.Fill(dt);
    connection.Close();
}
catch(SqlException e)
...

Hech qanday istisno emas. Qidiruvdan keyin nima uchun dt bo'sh? (Birlashma mag'lubiyatga ega bo'lsa, tanlov ishlaydi.) Nima bo'ldi?

Greetz

2
ustun nomini parametr sifatida berolmaysiz
qo'shib qo'ydi muallif Lucas_Santos, manba
ishlaydigan tarkibiy qo'shimchani qo'shing
qo'shib qo'ydi muallif Reniuz, manba
SqlParameter yo'li juda ham toza, shunga o'xshash. Mening kodim nima uchun ishlamayotgani qiziq. @Lucas_Santos Men uni ustun nomiga o'zgartirdim, lekin dt hali bo'sh. Greetz
qo'shib qo'ydi muallif hofmeister, manba

3 javoblar

Bunday parametrlardan foydalanib maydon nomlarini aniqlay olmaysiz. Sizning kodingiz WHERE @FROM @ SEARCHSHING qoidasida @FROM parametrining qiymati @SEARCHSTRING parametrining qiymatiga teng.

Agar qaerda qoidalar haqiqatga qarab baholanadigan bo'lsa, siz har qanday yozuvni lug'at jadvalida olasiz, agar u noto'g'ri deb hisoblasa, siz hech qanday yozuvni olmaysiz. Lug'at jadvalidagi domen nomi sifatida @ tarkibidan hech qachon foydalanilmaydi.

2
qo'shib qo'ydi
Ha, agar ular bir xil bo'lsa, siz butun jadvalni olasiz. Domen nomlarini ko'rsatish uchun parametrlardan foydalanmoqchi bo'lsangiz, Sql magistrini dinamik ravishda yaratishingiz kerak bo'ladi. Buning eng xavfsiz usuli spExecuteSql dan foydalanish msdn.microsoft.com/en- biz/kutubxona/ms188001.aspx
qo'shib qo'ydi muallif Ben Robinson, manba
OK, men uni sinab ko'rdim va sen haqsan! Muammo haqiqatan qaerda. (Ustun holatidagi parametrlar yaxshi ishlaydi). Yaxshiroq tushunish uchun, agar ikkala qiymatni ham taqqoslaydigan WHERE @FROM Like @SEARCHSHOW , to'liq jadvalni olasizmi? @FROM da parametrni kiritish mumkinmi yoki faqat shu holatda CommandText mag'lubiyatini aralashtirishim kerakmi? Rahmat, salom.
qo'shib qo'ydi muallif hofmeister, manba

Bu erda odamlar aytganidek, maydon nomlarini parametr sifatida qabul qilolmaysiz.

Siz olib boradigan yondashuv bir necha sabablarga ko'ra yomon fikrdir. Birinchidan, agar siz SQL buyrug'ini shu tarzda topshirsangiz, server so'rovni har safar amalga oshirganingizda uni qayta kompilyatsiya qilishi kerak, bu qo'shimcha yukni serverga qo'yadi va ishlashni sekinlashtiradi. Ikkinchidan, bu sizning tanlagan so'zlaringizni sizning jadvalingizning tuzilishiga qaramaydigan har qanday odamga bergani kabi xavfsizlikning xavfsizligi. Uchinchidan, bu kabi iboralarni ishlatish, agar nusxa ko'chirish yapmadan siz kirita olmaydigan kodni qayta ishlatishni istasangiz, bu degani.

Men taklif qiladigan narsa o'zida saqlab turilgan jarayonga o'tish. siz hali ham o'z parametrlari va boshqalar orqali o'tishingiz mumkin, lekin u kodni yaxshilaydi, chunki u SQL-ni siqib chiqaradi va faqat tegishli bo'lgan narsani qoldiradi.

Agar sizga bu kabi tanlovda foydalanish uchun maydon nomlaridan o'tish zarur bo'lsa, buni SQLda bajarishingiz va so'rovlar dizesini yaratishingiz mumkin, keyin esa uni sp_executesql yordamida bajarishingiz mumkin.

Asosan nima qilayotganingizni so'rovlar qatori deb e'lon qilish

DECLARE @queryString VARCHAR(3000)

SET @queryString ='SELECT id, '[email protected]+' AS from, '[email protected]+' AS to FROM Dictionary WHERE +'@FROM+' LIKE %'[email protected]+'%'

keyin @queryString dasturini ishlatish uchun sp_executesql foydalaning

So'rovlar chizig'ini qurishda biron bir xatolik yuzaga kelsa-da, Varchar parametrlarini uzatishingiz kerak bo'lishi mumkin

1
qo'shib qo'ydi
@Test so'rovlar jadvalini ko'rsatish uchun yuborgan misolni%
qo'shib qo'ydi muallif Purplegoldfish, manba
@Taz buni tekshirib ko'ring, juda sodda, ammo uni qanday qilib biroz kengaytirish mumkinligini ko'rsatadi. pastebin.com/tZqQpzmW
qo'shib qo'ydi muallif Purplegoldfish, manba
@taz Siz odatda ustunni = 'stringtext' qilsangiz, lekin siz yaratgan mag'lubiyatdan foydalansangiz column = stringtext '' nima qilish kerak bo'lmasa, bu belgilarga kiritilganligiga ishonch hosil qiling. Serverga o'tayotgan param
qo'shib qo'ydi muallif Purplegoldfish, manba
Ha, albatta, maydon nomlarini berish kerak. Oxirgi foydalanuvchi, tanlangan ustunni ochadigan ro'yxat bilan o'zgartirishi mumkin (men buni xavfsiz deb bilaman, lekin boshqa yo'lni bilmayman). Agar men sizni to'g'ri tushunsam yaxshiroq, protsedura yaratish, tartibda dinamik maydonlarni qo'shish va parametrlarni C# ichida "to'g'ri" sintaksisi "> bu erda . Bundan tashqari, SQL yangilanishlari uchun o'chiriladi va h.k. Greetz
qo'shib qo'ydi muallif hofmeister, manba
OK, siz aytganidek, tartib-qoidani qo'shib qo'ydim. Endi "% va%" ni qidirish satriga qo'shish kerak bo'lgan muammom bor. V # kodida bu muammo emas va hamma narsa yaxshi ishlaydi, lekin SQL Serverdan amaliyotni bajarishim uchun qanday qilib bitta taklif qo'sha olaman? C# da bajaraman: cmd.Parameters ["@ SEARCHSTRING"]. Value = "'% string%'"; . SQL serverida exec test_ usuli bajarildi @FROM = 'FROMVALUE', @TO = 'TOVALUE', @SEARCHSTRING = 'STRING' . Greetz
qo'shib qo'ydi muallif hofmeister, manba
Xo'sh, u ishlaydi, lekin agar teng bo'lsa ( = ) tanlamoqchi bo'lsam, agar bitta ustun bo'lsa, masalan, bir varchar bo'lsa. SQL serverida xatolik yuz beradigan amaliyotni qanday amalga oshirishim mumkinligini bilish qiziq. Haqiqiy muammo hal qilindi. Greetz
qo'shib qo'ydi muallif hofmeister, manba
Mhm, protsedurani noto'g'ri tushunmaslik uchun to'g'ri ishlaydi. Agar parametr mag'lubiyatga ega bo'lsa, SQL serveridan amaliyotni qanday bajarish mumkinligini bilishni istayman. Misol uchun, bu quyidagi amalni bajaradi: Procedure_Name @ FROM = coumn1, @ TO = coumn2, @ SEARCHSTRING = SEARCHSTRING , SQL server menga SEARCHSTRING Bu to'g'ri. Qidirish uchun to'g'ri sintaksisi ['SEARCHSTRING'] hisoblanadi. Hammaga rahmat! Greetz.
qo'shib qo'ydi muallif hofmeister, manba

Nega bunday so'rov so'ralgan?

   "SELECT id, @FROM AS \"from\", @TO AS \"to\" FROM Dictionary WHERE @FROM LIKE @SEARCHSTRING";

@FROMni jadvaldan olib chiqishga harakat qilyapsiz va uni parametr sifatida ishlashga harakat qilyapsizmi? Bundan tashqari, nega siz plashlarni ham kiritdingiz? Ular shunchaki tartibsizlikni olib tashlashadi, ularni olib tashlashadi. A Tanlash so'rovi faqatgina "WHERE" bandida va boshqa hech yerda kirish parametrlarini oladi.

Buning o'rnini almashtirishga harakat qiling

"SELECT id, FROM AS 'from', TO AS 'to' FROM Dictionary WHERE FROM LIKE @SEARCHSTRING";

Bundan tashqari, oxirgi marta ro'y beradigan voqealarni hammasini olib tashlang:

sqlSelect.SelectCommand.Parameters.Add

Shuningdek, "FROM" ning SQL kalit so'zi ekanligiga diqqat qiling, shuning uchun uni "[]" ga qo'shish orqali to'g'ri yo'l bilan talqin qiling.

Umid qilamanki ...

0
qo'shib qo'ydi