.Net 的简单 SQL 语句生成器

发布于 2024-07-13 10:05:02 字数 695 浏览 4 评论 0原文

我作为自由职业者加入了一家大公司正在进行的 .Net 2.0 Web 应用程序项目。 他们的 DAL 有许多手动构造和执行 SQL 语句的函数——其中许多函数又长又乱,因此难以理解和调试。 我写了一个简单的“sql helper”,让我可以写这样的东西:

sqlh.addValue("name", name);
sqlh.addValue("address, address);
sqlh.addLiteral("created", "getDate()");

string sql = String.Format("INSERT INTO [Table1] ({0}) values ({1})", sqlh.getInsertFields(), sqlh.getInsertValues());

它处理空值并且也适用于更新。 就是这样。

理想情况下,我会使用 Microsoft 数据应用程序块或 LINQ 等,但目前不可能进行重大架构更改。 这种方法节省了我很多时间,但似乎最好通过使用“社区批准”的解决方案来解决问题。

Microsoft 或其他公司是否有一种流行的轻量级解决方案可以实现类似的结果?

编辑

虽然到目前为止描述的 SqlParameter 解决方案是对纯手动语句构建方法的改进,但我认为我仍然更喜欢我的解决方案,其中从查询中添加或删除字段仅影响单行。 还有更好的吗? 谢谢

I've jumped into an ongoing .Net 2.0 web app project for a larger company as a freelancer. Their DAL has lots of functions that manually construct and execute SQL statements -- many of them are long, messy and as a result difficult to understand and debug. I wrote a simple "sql helper" that lets me write things like this:

sqlh.addValue("name", name);
sqlh.addValue("address, address);
sqlh.addLiteral("created", "getDate()");

string sql = String.Format("INSERT INTO [Table1] ({0}) values ({1})", sqlh.getInsertFields(), sqlh.getInsertValues());

It handles nulls and also works for updates. That's about it.

Ideally I would be using Microsoft Data Application block or LINQ or something, but major architectural changes are not possible at this point. This method has saved me a lot of time, but seems like a problem best solved by using a "community-approved" solution.

Is there a popular, light-weight solution that achieves similar results, from Microsoft or otherwise?

EDIT

While the SqlParameter solutions described so far are an improvement over a purely manual statement building method, I think I still prefer my solution, where adding or removing a field from the query affects only a single line. Anything better? thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我的影子我的梦 2024-07-20 10:05:02

Microsoft 有多种选择:ADO.NET 或 Linq2Sql 是目前流行的选择。 但是你提到的链接,从生成 SQL 转换为 ORM 需要大量的工作。

为了使 SQL 的创建更直接、更安全,您应该考虑使用 SQL 参数。 这是一个示例:

using (SqlCommand saveCommand = DbUtil.CreateSqlCommand(context.Transaction)) {
    saveCommand.CommandText =
        "INSERT INTO Hit (" +
            "Id, PersonId, TeamId, PlayerId" +
        ") VALUES (" +
            "@Id, @PersonId, @TeamId, @PlayerId" +
        ")";

    DbUtil.AddParameter(saveCommand, "@Id", SqlDbType.UniqueIdentifier, Guid.NewGuid());
    DbUtil.AddParameter(saveCommand, "@PersonId", SqlDbType.UniqueIdentifier, hit.PersonId);
    DbUtil.AddParameter(saveCommand, "@TeamId", SqlDbType.UniqueIdentifier, hit.TeamId);
    DbUtil.AddParameter(saveCommand, "@PlayerId", SqlDbType.UniqueIdentifier, hit.PlayerId);

    saveCommand.ExecuteNonQuery();
}

这会将参数列表与 SQL 分开。 SQL 也变得更加清晰。 示例中的 DbUtil 只是我编写的一个辅助函数,用于从连接或事务创建 sql 命令。 也类似于您的 sqlh.addValue,我有一个 DbUtil.AddParameter,它通过接收命令、变量名称、数据类型和值来工作。 这是一个包含重载方法的示例:

internal static SqlParameter CreateSqlParameter(
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction,
    object value
) {
    SqlParameter parameter = new SqlParameter(parameterName, dbType);

    if (value == null) {
        value = DBNull.Value;
    }

    parameter.Value = value;
    parameter.Direction = direction;
    return parameter;
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType
) {
    return AddParameter(sqlCommand, parameterName, dbType, null);
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    object value
) {
    return AddParameter(sqlCommand, parameterName, dbType, ParameterDirection.Input, value);
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction,
    object value
) {
    SqlParameter parameter = CreateSqlParameter(parameterName, dbType, direction, value);
    sqlCommand.Parameters.Add(parameter);
    return parameter;
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction
) {
    SqlParameter parameter = CreateSqlParameter(parameterName, dbType, direction, null);
    sqlCommand.Parameters.Add(parameter);
    return parameter;
}

You have several options from Microsoft: ADO.NET or Linq2Sql are the popular ones at this time. But link you mentioned, it will take a good amount of work to convert from generating SQL to an ORM.

To make the creation of SQL more straight-forward and safer, you should consider using SQL Parameters. Here is an example:

using (SqlCommand saveCommand = DbUtil.CreateSqlCommand(context.Transaction)) {
    saveCommand.CommandText =
        "INSERT INTO Hit (" +
            "Id, PersonId, TeamId, PlayerId" +
        ") VALUES (" +
            "@Id, @PersonId, @TeamId, @PlayerId" +
        ")";

    DbUtil.AddParameter(saveCommand, "@Id", SqlDbType.UniqueIdentifier, Guid.NewGuid());
    DbUtil.AddParameter(saveCommand, "@PersonId", SqlDbType.UniqueIdentifier, hit.PersonId);
    DbUtil.AddParameter(saveCommand, "@TeamId", SqlDbType.UniqueIdentifier, hit.TeamId);
    DbUtil.AddParameter(saveCommand, "@PlayerId", SqlDbType.UniqueIdentifier, hit.PlayerId);

    saveCommand.ExecuteNonQuery();
}

That will separate your parameter list from the SQL. Also the SQL we be much more legible. The DbUtil in the example is just a helper function I wrote to create my sql command from a connection or transaction. Also similar to your sqlh.addValue, I have a DbUtil.AddParameter that works by taking in the command, variable name, data type and value. Here's a sample including overloaded methods:

internal static SqlParameter CreateSqlParameter(
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction,
    object value
) {
    SqlParameter parameter = new SqlParameter(parameterName, dbType);

    if (value == null) {
        value = DBNull.Value;
    }

    parameter.Value = value;
    parameter.Direction = direction;
    return parameter;
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType
) {
    return AddParameter(sqlCommand, parameterName, dbType, null);
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    object value
) {
    return AddParameter(sqlCommand, parameterName, dbType, ParameterDirection.Input, value);
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction,
    object value
) {
    SqlParameter parameter = CreateSqlParameter(parameterName, dbType, direction, value);
    sqlCommand.Parameters.Add(parameter);
    return parameter;
}

internal static SqlParameter AddParameter(
    SqlCommand sqlCommand,
    string parameterName,
    SqlDbType dbType,
    ParameterDirection direction
) {
    SqlParameter parameter = CreateSqlParameter(parameterName, dbType, direction, null);
    sqlCommand.Parameters.Add(parameter);
    return parameter;
}
奈何桥上唱咆哮 2024-07-20 10:05:02

我创建了自己的存储过程来根据给定的表模式创建插入语句,我认为我非常棒。 然后我发现了这个:

创建过程 sp_generate_inserts

编辑

我知道我发现了这一点脚本是以前的 SO 帖子的结果,但我现在找不到它,如果其他人知道或知道,请编辑/或添加到评论,我将编辑。

I created my own stored procedure to create insert statements based on a given table schema, I thought I was pretty awesome. Then I found this:

CREATE PROC sp_generate_inserts

EDIT

I know that I found about that script as a result of a previous SO post, but I can't find it now, if someone else does or knows, please edit/or add to comment and I will edit.

海拔太高太耀眼 2024-07-20 10:05:02

SqLCommand 和 SQLParameter 对象可能对您有用:

  Dim sc As New SqlClient.SqlCommand

  Dim sp As New SqlClient.SqlParameter("@value", SqlDbType.VarChar)
  sp.Value = "test"

  sc.Parameters.Add(sp)
  sc.CommandText = "select column1, column2 from table where column3=@value"

  sc.ExecuteReader()

它是 vb.net,但您明白了。 这将有助于防止 sql 注入,并且看起来整洁且可读。

不要忘记设置连接字符串等。

SqLCommand and SQLParameter objects might be of use to you:

  Dim sc As New SqlClient.SqlCommand

  Dim sp As New SqlClient.SqlParameter("@value", SqlDbType.VarChar)
  sp.Value = "test"

  sc.Parameters.Add(sp)
  sc.CommandText = "select column1, column2 from table where column3=@value"

  sc.ExecuteReader()

Its vb.net but you get the idea. This will help prevent sql injection, and looks neat and is readable too.

Dont forget to setup your connection string etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文