如何转换SqlCommand查询以使用使用包括三元运算符的变量的级联字符串构建的参数

问题描述 投票:2回答:1

这是我的第一个问题,希望我做正确的事。另外,作为序言,自从我们离开现在的程序员以来,我是一个编程新手,负责在我工作的地方开发和修复一些代码。如果我目前的知识有限,如果现在做得很好。

我正在尝试尽可能多地修复各种程序中某些代码的结构,其中一部分正在将所有(或大多数)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;

如您所见,我已经能够用参数替换很多命令,我只是不知道如何用其他字符串变量来实现它。上面的命令按原样工作,但是如果可能的话,我想用参数替换其余的字符串,而不是执行当前的串联操作。我还有其他使用类似结构的应用程序,但希望如果我能看到解决方法,可以将其应用于其余结构。

不确定当前的做法是否是当前的良好做法,但是我也不能使它过于复杂。

字符串变量根据某些复选框的状态获取其值。

任何帮助将不胜感激。我也看到过类似的问题,但是我无法正确掌握解决方案,因此希望通过个人示例可以使它起作用。

或者,也许还不错,我不应该更改它?

c# conditional-operator sqlcommand sqlparameter
1个回答
0
投票

用SQL语句本身内的seeCORES语句处理seeSINCORESseeHOLDSor的不同可能性。在阅读下面的内容时,可能会有助于记住,在sql server中,andor之前先被处理。

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部分,从布尔值到位的转换可能只适用于变量本身。

不过请注意,在您的原始代码中,我相信将seeCORESseeSINCORES都设置为true将产生与将它们都设置为false相似的输出。唯一的区别是,如果pickuptype中有任何空值,则将它们都设置为false会给出更多记录。这是预期的行为吗? (修辞性问题)。

© www.soinside.com 2019 - 2024. All rights reserved.