SelectCommand with Parameters забезпечує порожній результат

В даний час я очищу мій код трохи, і VS сказав мені, краще використовувати для команд sql SqlParameter замість складного string . Тому я вирішив змінити свій код, на жаль, зараз я не отримаю результат, і я не знаю чому. Ось фрагмент мого коду:

...    
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)
...

Я не отримую ніяких винятків. Чому dt порожній після пошуку? (У складному рядку вибрати працює.) Що сталося не так?

Грітц

2
ви не можете передати назву стовпця як параметр
додано Автор Lucas_Santos, джерело
додайте свій складний рядок, який працював
додано Автор Reniuz, джерело
Шлях SqlParameter набагато чистий, мені це подобається. Було б цікаво, чому мій код не працює. @ Lucas_Santos Я змінив його в назву стовпця, але dt все ще порожній. Грітц
додано Автор hofmeister, джерело

3 Відповіді

Ви не можете вказати імена полів за допомогою таких параметрів. У вашому місці WHERE @FROM LIKE @SEARCHSTRING він порівнює значення параметра @FROM з значенням параметра @SEARCHSTRING .

Якщо депозит оцінюється як true, ви отримаєте кожен запис у словниковій таблиці, якщо воно оцінюється фальшивим, ви не отримаєте жодних записів. Він ніколи не розглядатиме вміст @from як ім'я поля в словнику.

2
додано
Так, якщо вони однакові, ви отримаєте весь стіл. Вам доведеться динамічно будувати строку Sql, якщо ви хочете використовувати параметри, щоб вказати імена полів. Найбезпечніший спосіб це зробити - це використовувати spExecuteSql msdn.microsoft.com/en- us/library/ms188001.aspx
додано Автор Ben Robinson, джерело
Добре, я протестував це, і ти маєш рацію! Проблема насправді є депозитом. (Параметри в позиції стовпця добре працюють). Для кращого розуміння WHERE @FROM LIKE @SEARCHSTRING , порівнюючи обидва значення, якщо вони однакові, я отримаю повну таблицю, чи не так? Чи можна додати параметр в @FROM , або просто з'єднати рядок CommandText в цю позицію? Дякую, привіт
додано Автор hofmeister, джерело

Як сказано тут, проблема полягає в тому, що ви не можете передавати імена поля як параметри.

Підхід, який ви використовуєте, є поганою ідеєю з кількох причин: по-перше, коли ви передаєте команду sql таким чином, сервер повинен перекомпілювати його кожного разу, коли ви виконуєте цей запит, це ставить додаткове навантаження на сервер і уповільнює продуктивність. По-друге, це небезпека для безпеки, яка передає ваші вибрані твердження, як це, оскільки це дає змогу будь-кому, хто перехоплює його, переглянути структуру вашої таблиці. По-третє, використовуючи виражені висловлювання, це означає, що коли ви хочете повторно використовувати код, який ви не можете скопіювати.

Що я хотів би запропонувати, це перехід на збережену процедуру. ви все одно можете передавати свої параметри тощо, але це покращить ваш код, оскільки він приймає SQL з C# і залишає тільки те, що є релевантним.

Якщо вам дійсно потрібно передати назви поля, які будуть використовуватися в операторі select, як це ви можете зробити це в SQL і створити рядок запиту, а потім виконати його за допомогою sp_executesql.

В основному те, що ви робите, це оголосити рядок запиту як

DECLARE @queryString VARCHAR(3000)

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

тоді просто використовуйте sp_executesql для виконання @queryString

Можливо, вам доведеться виставити параметри як Varchar, хоча, якщо ви отримаєте помилки під час створення строки запиту

1
додано
@Taz I оновив приклад, який я опублікував, щоб показати рядок запиту з%
додано Автор Purplegoldfish, джерело
@Taz перевірити це, це досить простий, але він показує, як це можна трохи розширити pastebin.com/tZqQpzmW
додано Автор Purplegoldfish, джерело
@taz При виборі рядка ви зазвичай виконуєте column = 'stringtext', але коли ви використовуєте змінні, стовпчик, який ви створюєте, закінчується, схоже на стовпець = stringtext без '', що вам потрібно зробити, це переконайтеся, що ці символи включені в параметр передається на сервер
додано Автор Purplegoldfish, джерело
Так, мені дійсно потрібно передати назви полів. Кінцевий користувач міг змінити зі спадного списку вибраного стовпця (я знав, що це не безпечно, але я не знаю інший спосіб). Якщо я правильно вас зрозумів, краще, створити процедуру, додати в процесі динамічно поля та додати такі параметри, як тут в c #. Також для sql оновлення, видалення і так далі? Грітц
додано Автор hofmeister, джерело
Гаразд, я додав таку процедуру, як ви сказали. Тепер у мене виникла проблема, що я повинен додати '% and%' до рядка пошуку. У коді C# це не проблема, і все працює нормально, але як я можу додати одну цитату, якщо виконую процедуру з sql-сервера? У C# я роблю: cmd.Parameters ["@ SEARCHSTRING"]. Значення = "'% string%'"; . На сервері sql я виконував exec test_ procedure @FROM = 'FROMVALUE', @TO = 'TOVALUE', @SEARCHSTRING = 'STRING' . Грітц
додано Автор hofmeister, джерело
Ну, це працює, але якщо я намагаюся вибрати з однаковими ( = ), то одиночні лапки відсутні, якщо стовпчик є, наприклад, varchar. Мені було б цікаво дізнатись, як я можу виконати процедуру, яка очікує жаху на сервері sql. Фактична проблема вирішена. Грітц
додано Автор hofmeister, джерело
Ммм, щоб уникнути непорозумінь, процедура працює правильно. Я хотів би знати, як я можу виконати процедуру з sql-сервера, якщо параметр є рядком. Якщо я виконаю, наприклад, це: Procedure_Name @ FROM = coumn1, @ TO = coumn2, @ SEARCHSTRING = SEARCHSTRING , сервер sql повідомляє мені, що SEARCHSTRING не є стовпцем це правильно. Правильний синтаксис пошуку є ['SEARCHSTRING'] . Дякую всім! Грітц
додано Автор hofmeister, джерело

Чому ви написали запит подібним чином?

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

Ви намагаєтесь отримати @FROM з таблиці, а також намагатися передавати його як параметр, який повинен працювати? Також чому б ви включили косу рисунки? вони просто роблять речі брудними, видаляють їх. Вибраний запит приймає вхідні параметри тільки з пунктом "WHERE" і ніде більше.

Спробуйте замінити це цим

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

Також видаліть всі, окрім останніх, події:

sqlSelect.SelectCommand.Parameters.Add

Також подбайте про те, щоб "ВІД" було також ключовим словом SQL, тому переконайтеся, що його правильно інтерпретувати, додавши його в "[]".

Сподіваюся, це допоможе ...

0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug