如何将 SqlCommand 查询转换为使用使用连接字符串构建的参数,包括使用三元运算符的变量

How to convert SqlCommand query to use parameters built using concatenated strings including variables using ternary operators

这是我的第一个问题,希望我做对了。另外作为序言,我是一个编程菜鸟,负责开发和修复一些代码,因为我们的程序员已经离开了。如果以我有限的知识目前做得很好的话。

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

如您所见,我已经能够用参数替换很多命令,我只是不知道如何用其他字符串变量来实现它。上面的命令按原样工作,但如果可能的话,我想用参数替换其余的字符串,而不是执行我目前的连接。我还有其他使用类似结构的应用程序,但希望如果我能看到如何修复这个问题,我就能将它应用到其他应用程序。

不确定我一直在做的事情是否是当前的好做法,但我也不能把它弄得太复杂。

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

如有任何帮助,我们将不胜感激。我见过类似的问题,但我一直无法正确掌握解决方案,所以希望通过一个个人例子,我能够让它发挥作用。

或者,也许它就这样很好,我不应该改变它?

编辑:对@pwilcox 给出的答案进行了初步测试,它似乎在工作,至少 SQL 查询正在通过,我没有错误,结果看起来像我期待的。如果正确,那么希望我现在能够将此逻辑应用于其他需要改进的情况。

谢谢!

在 SQL 语句本身中使用 or 语句处理 seeCORESseeSINCORESseeHOLDS 的不同可能性。在阅读下文时,记住在 sql 服务器中,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 将提供更多记录。这是预期的行为吗? (反问)。