【问题标题】:How to set dynamic params for SQL query in C#如何在 C# 中为 SQL 查询设置动态参数
【发布时间】:2021-04-27 07:17:21
【问题描述】:

您好,我必须为 {0}{1} 添加动态参数,但我不知道它是如何工作的。有人可以帮我解释一下吗?

 string strCmdExclChainLast = string.Format("SELECT SUM(F9H.PCPQ9H) AS ValueLast " +
                                                   "FROM {3}.F9H00 F9H " +
                                                   "WHERE F9H.PCPU9H = " +
                                                                       "(SELECT C02.YMDU02 " +
                                                                       "FROM {3}.C0200 C02 " +
                                                                       "WHERE C02.HTYC02 = '0' AND C02.YMDU02 < {0}{1}{2} " +
                                                                       "ORDER BY C02.YMDU02 DESC " +
                                                                       "FETCH FIRST ROW ONLY) " +
                                                   "AND F9H.LN1C9H NOT IN ('130', '211', '311', '360', '411', '530', '540')",
                                                   DateTime.Now.Year,
                                                   DateTime.Now.Month.ToString().Length == 1 ? "0" + DateTime.Now.Month.ToString() : DateTime.Now.Month.ToString(),
                                                   DateTime.Now.Day.ToString().Length == 1 ? "0" + DateTime.Now.Day.ToString() : DateTime.Now.Day.ToString(),
                                                   Program.Wavedlib);

        dtExclChain.Rows[0]["ValueLast"] = DBOps.ExecDataTableDB2AS400(strCmdExclChainLast).Rows[0]["ValueLast"];

【问题讨论】:

  • 不要连接字符串:使用参数。
  • 您的 DBMS 是什么?你用什么与 C# 中的数据库进行通信? Mitch 是对的,我们通常会有一个数据库类,让我们可以直接将参数作为日期传递。但是,这不适用于架构名称。 YMDU02 是什么数据类型?你的查询结果是什么?您是否从 DBMS 收到错误消息?
  • 为什么你必须通过日期?你的 DBMS 不知道今天是星期几吗?
  • DBMS = 数据库管理系统,意思是,你使用的“数据库引擎”是什么。例如:MySQL、Microsoft SQL Server、Oracle DB、Sqlite、PostgreSQL,……每个都使用自己的 SQL 语言“风味”,以及一些内部细节,以及一些可能或可能不是的特性在其他人中可用或建议使用。

标签: c# sql


【解决方案1】:

对于此任务,您可以使用 Dapper (https://github.com/DapperLib/Dapper)。这是一个非常轻量级的库。 此库与 string.Format 非常相似,但在您要构建 SQL 查询时它可以正常工作。

例如,它是这样工作的。

public class Dog
{
    public int? Age { get; set; }
    public Guid Id { get; set; }
    public string Name { get; set; }
    public float? Weight { get; set; }

    public int IgnoredProperty { get { return 1; } }
}

var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

Assert.Equal(1,dog.Count());
Assert.Null(dog.First().Age);
Assert.Equal(guid, dog.First().Id);

【讨论】:

    【解决方案2】:

    如果在 SQL 查询的开头放置 $@ 符号,则可以在查询中使用动态参数和特殊字符。像这样:

    $@"SELECT SUM(F9H.PCPQ9H) AS ValueLast " +
                                                   "FROM {3}.F9H00 F9H " +
                                                   "WHERE F9H.PCPU9H = " +
                                                                       "(SELECT C02.YMDU02 " +
                                                                       "FROM {3}.C0200 C02 " +
                                                                       "WHERE C02.HTYC02 = '0' AND C02.YMDU02 < {0}{1}{2} " +
                                                                       "ORDER BY C02.YMDU02 DESC " +
                                                                       "FETCH FIRST ROW ONLY) " +
                                                   "AND F9H.LN1C9H NOT IN ('130', '211', '311', '360', '411', '530', '540')"
    

    我们可以这样做,但我们不应该选择它。因为这使我们的查询容易受到 SQL Inj 攻击。

    【讨论】:

    • 可以查看这篇关于sql注入的文章netsparker.com/blog/web-security/sql-injection-cheat-sheet
    • 永远不要在 sql 查询中使用直接变量。在许多情况下,这应该不是问题,但在某些情况下,我可能能够将您的变量设置为“... DROP DATABASE;--”。几年前,我能够通过将“UNION SELECT”注入网站 id 参数来读取社区用户的信用卡信息
    • 我想我们已经明确了如何做到这一点以及为什么不应该这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2020-04-11
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多