Как преобразовать запрос SqlCommand для использования параметров, построенных с использованием объединенных строк, включая переменные, с использованием троичных операторов - PullRequest
2 голосов
/ 20 февраля 2020

это мой первый вопрос, надеюсь, я все делаю правильно. Также к предисловию, я нуб-программист, которому поручено разрабатывать и исправлять некоторый код, в котором я работаю с тех пор, как ушел наш программист. И если пока все сделано достаточно хорошо с моими ограниченными знаниями.

Я пытаюсь как можно больше исправить структуру некоторого кода в различных программах, и часть его преобразует все (или большинство) SqlCommand для использования параметров. Я застрял, когда код вызывает строковые переменные с использованием тернарного оператора (? :) и использует несколько этих строк для объединения полной командной строки SQL.

Например:

string RecogidosCoresString    = seeCORES ? " and [PICKUPTYPE] = 2 " : " ";
string RecogidosSinCoresString = seeSINCORES ? " and [PICKUPTYPE] <> 2 " : " ";
string RecogidosHolds          = seeHOLDS ? " and [PICKUPSTATUS] = 1 " : " and [PICKUPSTATUS] > 1 ";

string stringreadHeader = "SELECT * FROM [RecogidosHeader] WHERE [ENTRYDATE] >= @EntryDate1 AND [ENTRYDATE] < @EntryDate2 AND ([PICKUPNMBR] = @RecogidoID OR CUSTNMBR = @CustNumb )";

SqlCommand readHeader = new SqlCommand(stringreadHeader + RecogidosHolds + RecogidosCoresString + RecogidosSinCoresString + "Order By [PICKUPNMBR] ASC", AppsConnect);

readHeader.Parameters.Add("@EntryDate1", SqlDbType.DateTime).Value = dateTimePicker1.Value.ToShortDateString();
readHeader.Parameters.Add("@EntryDate2", SqlDbType.DateTime).Value = dateTimePicker2.Value.AddDays(1).ToShortDateString();
readHeader.Parameters.Add("@RecogidoID", SqlDbType.VarChar, 50).Value = textBox1.Text;
readHeader.Parameters.Add("@CustNumb", SqlDbType.VarChar, 50).Value = textBox1.Text;

Как видите, я смог заменить большую часть команды параметрами, я просто не знаю, как реализовать ее с другими строковыми переменными. Приведенная выше команда работает как есть, но, если возможно, я бы хотел заменить остальные строки параметрами вместо того, чтобы выполнять конкатенацию, которая у меня есть в настоящее время. У меня есть другие приложения, использующие аналогичные структуры, но, надеюсь, если я увижу, как исправить это, я смогу применить его к остальным.

Не уверен, что мой подход к этому хорош. в настоящее время, но я не могу слишком усложнить это.

Строковые переменные получают свои значения в зависимости от состояния некоторых флажков.

Любая помощь будет принята с благодарностью. Я видел подобные вопросы, но я не смог правильно asp найти решения, так что, надеюсь, на личном примере я смогу заставить его работать.

Или, может быть, это нормально как есть, и я не должен его менять?

Редактировать: Предварительное тестирование ответа @pwilcox дало, и, похоже, оно работает, по крайней мере, запрос SQL проходит, и я нет ошибок, и результаты кажутся теми, которые я ожидаю. Если все правильно, то, надеюсь, теперь я смогу применить эту логику c к другим ситуациям, которые нуждаются в улучшении.

Спасибо!

1 Ответ

1 голос
/ 20 февраля 2020

Обрабатывайте различные возможности seeCORES, seeSINCORES и seeHOLDS с помощью операторов or внутри самого оператора SQL. При чтении ниже это может помочь вспомнить, что на sql сервере and обрабатывается первым, прежде чем or.

string stringreadHeader = @"
    select      * 
    from        recogidosHeader
    where       entrydate >= @EntryDate1 
    and         entrydate < @EntryDate2 
    and         (pickupnmbr = @RecogidoID or custnmbr = @CustNumb)

    and         (@seeCORES = 1 and pickuptype = 2 or @seeCORES = 0)
    and         (@seeSINCORES = 1 and pickuptype <> 2 or @seeSINCORES = 0)
    and         (
                       @seeHOLDS = 1 and pickupstatus = 1
                    or @seeHOLDS = 0 and pickupstatus > 1
                )

    order by    pickupnmbr
";

...
readHeader.Parameters.Add("@seeCORES", SqlDbType.Bit).Value = seeCORES ? 1 : 0;
readHeader.Parameters.Add("@seeHOLDS", SqlDbType.Bit).Value = seeHOLDS ? 1 : 0;

Я не знаю, нужна ли вам часть ? 1 : 0, преобразование от логического значения к двоичному может просто работать с переменными в том виде, в каком они есть.

Просто чтобы заметить, хотя, в вашем исходном коде, я считаю, что установка seeCORES и seeSINCORES для обоих значений в true даст очень похожий результат для установки они оба ложные. Единственная разница будет в том, что установка их обоих в false даст БОЛЬШЕ записей, если в pickuptype есть какие-либо нулевые значения. Это предполагаемое поведение? (риторический вопрос).

...