2009-01-23 105 views
0

我已经为一个更大的公司作为自由职业者跳入正在进行的.Net 2.0 Web应用程序项目。他们的DAL具有许多手动构建和执行SQL语句的功能 - 其中很多都是漫长而混乱的,因此很难理解和调试。我写了一个简单的“SQL助手”,让我这样写:.Net的简单SQL语句生成器

 
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()); 

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

理想情况下,我会使用微软数据应用程序块或LINQ或其他东西,但在这一点上主要的体系结构变化是不可能的。这种方法为我节省了很多时间,但似乎是通过使用“社区认可”解决方案最好解决的问题。

是否有一种流行的轻量级解决方案能够实现类似的结果,从Microsoft或其他方面?

编辑

虽然到目前为止所描述的SqlParameter的解决方案是在一个纯手工的说明建立方法的改进,我想我还是喜欢我的解决方案,其中仅增加或从查询删除场影响单个线。有什么更好的?感谢

+0

getInsertValues()是做什么的? – AnthonyWJones 2009-01-23 16:46:08

+0

getInsertFields()=>“[name],[address],[created]” getInsertValues()=>''Bill','123 Street',getDate()“ – Bill 2009-01-23 16:57:11

回答

0

的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 [email protected]" 

    sc.ExecuteReader() 

其vb.net,但你的想法。这将有助于防止SQL注入,并且看起来整洁并且可读。

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

1

我创建了自己的存储过程创建一个基于给定表模式insert语句,我以为我是相当真棒。后来我发现这一点:

CREATE PROC sp_generate_inserts

编辑

我知道,我发现关于脚本作为之前的SO后的结果,但现在我不能找到它,如果其他人知道,请编辑/或添加评论,我会编辑。

1

您有几个选择来自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; 
}