sql注入问题

好奇都是要学的 2018-03-07 12:13:50
公司接了个新项目,为了快速开发用的拼接SQL。 但是很容易就被注入。 然后把关键字都替换成空,判断长度返回true 和false ,但是这样又造成了客户在添加简介 用英文描述的时候出错。 然后我想把关键字 前后都加上&符号存入数据库。在取出来查看的时候在把&去掉。或者注入的时候少不了输入单引号,我直接把'变成双引号不去管关键字了。 各位大神这样行吗? 会有什么后果

代码
string strSql = "select * from ShopCommodity where 1=1";
if (txtShopGoodName.Text.Trim() != "")
{
strSql += " and ShopGoodName like '%" + txtShopGoodName.Text + "%'";
}
if (ddlShopName.SelectedValue!= "0")
{
strSql += " and ShopID like '%" + ddlShopName.SelectedValue + "%'";
}
这样很容易通过文本框注入。 我提的解决办法是 把关键字替换了 比如select替换成&select& 然后把单引号替换成双引号。 这样是不是就没办法注入了。
...全文
1661 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
还想懒够 2018-03-23
  • 打赏
  • 举报
回复
引用 57 楼 wang2129929 的回复:
[quote=引用 56 楼 jjkk168 的回复:] [quote=引用 38 楼 jjkk168 的回复:] 这种有关SQL注入的贴子见过不下百个了 解决方案一:使用SqlParameter,这种方法其实很费事 解决方案二: 1. 所有字符型的,你管它来自于哪里,直接Replace("'","''"),即将单个单引号替换为两个单引号 2. 其余类型的,在拼接之前判断下是不是正常的类型,比如说int.Parse(Request["Key"])
讨论来讨论去,就没几个人知道单个单引号替换为两个单引号。注入首先就是防止单引号导致SQL语句出错,其次就是非字符类型的,需要先期用int.TryParse判断下是不是正常等。 有这么复杂么? 曾经还和一个自以为很懂的哥们,他也不做测试,死活认为不仅仅是单引号。非得犟! [/quote] 请问我把英文的单引号替换成中文的单引号 跟你说的是一个意思啊 这样的话 他输入的信息里 即使有英文的单引号 我也变成中文的 存入数据库,也支持查询了[/quote] 1. 并不需要替换为中文单引号,有些时候中文单引号反而有点怪。比如说I'm,didn't等。 2. 只需要将单引号替换为两个单引号,而不是替换为双引号
  • 打赏
  • 举报
回复
引用 58 楼 jjkk168 的回复:
[quote=引用 57 楼 wang2129929 的回复:] [quote=引用 56 楼 jjkk168 的回复:] [quote=引用 38 楼 jjkk168 的回复:] 这种有关SQL注入的贴子见过不下百个了 解决方案一:使用SqlParameter,这种方法其实很费事 解决方案二: 1. 所有字符型的,你管它来自于哪里,直接Replace("'","''"),即将单个单引号替换为两个单引号 2. 其余类型的,在拼接之前判断下是不是正常的类型,比如说int.Parse(Request["Key"])
讨论来讨论去,就没几个人知道单个单引号替换为两个单引号。注入首先就是防止单引号导致SQL语句出错,其次就是非字符类型的,需要先期用int.TryParse判断下是不是正常等。 有这么复杂么? 曾经还和一个自以为很懂的哥们,他也不做测试,死活认为不仅仅是单引号。非得犟! [/quote] 请问我把英文的单引号替换成中文的单引号 跟你说的是一个意思啊 这样的话 他输入的信息里 即使有英文的单引号 我也变成中文的 存入数据库,也支持查询了[/quote] 1. 并不需要替换为中文单引号,有些时候中文单引号反而有点怪。比如说I'm,didn't等。 2. 只需要将单引号替换为两个单引号,而不是替换为双引号[/quote] 感谢你的帮助,可用加你QQ 或者其他联系方式 , 在有问题的时候跟你学习下吗?
  • 打赏
  • 举报
回复
引用 38 楼 jjkk168 的回复:
这种有关SQL注入的贴子见过不下百个了 解决方案一:使用SqlParameter,这种方法其实很费事 解决方案二: 1. 所有字符型的,你管它来自于哪里,直接Replace("'","''"),即将单个单引号替换为两个单引号 2. 其余类型的,在拼接之前判断下是不是正常的类型,比如说int.Parse(Request["Key"])
感谢你的帮助,可以加你的QQ或者其他联系方式吗? 有问题的时候向你请教!
  • 打赏
  • 举报
回复
引用 56 楼 jjkk168 的回复:
[quote=引用 38 楼 jjkk168 的回复:] 这种有关SQL注入的贴子见过不下百个了 解决方案一:使用SqlParameter,这种方法其实很费事 解决方案二: 1. 所有字符型的,你管它来自于哪里,直接Replace("'","''"),即将单个单引号替换为两个单引号 2. 其余类型的,在拼接之前判断下是不是正常的类型,比如说int.Parse(Request["Key"])
讨论来讨论去,就没几个人知道单个单引号替换为两个单引号。注入首先就是防止单引号导致SQL语句出错,其次就是非字符类型的,需要先期用int.TryParse判断下是不是正常等。 有这么复杂么? 曾经还和一个自以为很懂的哥们,他也不做测试,死活认为不仅仅是单引号。非得犟! [/quote] 请问我把英文的单引号替换成中文的单引号 跟你说的是一个意思啊 这样的话 他输入的信息里 即使有英文的单引号 我也变成中文的 存入数据库,也支持查询了
还想懒够 2018-03-16
  • 打赏
  • 举报
回复
引用 38 楼 jjkk168 的回复:
这种有关SQL注入的贴子见过不下百个了 解决方案一:使用SqlParameter,这种方法其实很费事 解决方案二: 1. 所有字符型的,你管它来自于哪里,直接Replace("'","''"),即将单个单引号替换为两个单引号 2. 其余类型的,在拼接之前判断下是不是正常的类型,比如说int.Parse(Request["Key"])
讨论来讨论去,就没几个人知道单个单引号替换为两个单引号。注入首先就是防止单引号导致SQL语句出错,其次就是非字符类型的,需要先期用int.TryParse判断下是不是正常等。 有这么复杂么? 曾经还和一个自以为很懂的哥们,他也不做测试,死活认为不仅仅是单引号。非得犟!
  • 打赏
  • 举报
回复
过滤关键字和 单引号之类 是最基础的方法 最终还是 参数化 可靠
就叫彪哥 2018-03-15
  • 打赏
  • 举报
回复
最好的办法当然是参数化,如你觉得改成参数很麻烦,不防在Global.asax中加入以下代码 void Application_BeginRequest(object sender, EventArgs e) { // 在新会话启动时运行的代码 string str = HttpContext.Current.Request.QueryString.ToString(); string[] tsChar = { "%27", "'" }; for (int i = 0; i < tsChar.Length; i++) { if (str.Contains(tsChar[i])) { HttpContext.Current.Response.End(); return; } } } 以上代码的原理就是在整站的get请求中禁止输入单引号,除单引号我想不出还能有什么其它的方法注入,本人也用注入工具测试过没有问题,如果有人觉得我的代码有问题欢迎批评
  • 打赏
  • 举报
回复
我以前上海的公司就3个方法搞定 所有的存错过程, 取 数据集
public static DataView DisplayDataDetail(string strNo, string strSPName) //参数 , 存错过程命
{
Database db = DatabaseFactory.CreateDatabase("BusinessDb");
DbCommand cmd = db.GetStoredProcCommand(strSPName);

db.AddInParameter(cmd, "chrNo", DbType.String, strNo);

DataSet dst = db.ExecuteDataSet(cmd);
if (dst != null)
{
return dst.Tables[0].DefaultView;
}
else
{
return null;
}
}
新增或者修改
public static string SaveDataXML(string strXmlPara, string strSPName) 传进去XML 然后存错过程解析XML 在插入或者修改
{
Database db = DatabaseFactory.CreateDatabase("BusinessDb");
DbCommand cmd = db.GetStoredProcCommand(strSPName);
db.AddInParameter(cmd, "chrXML", DbType.String, strXmlPara); //XML组合文档
db.AddOutParameter(cmd, "chrReturn", DbType.String, 100);
try
{
db.ExecuteNonQuery(cmd);
return db.GetParameterValue(cmd, "chrReturn").ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 执行一条UPDATE、INSERT 或 DELETE 语句 返回影响的行数
/// </summary>
/// <param name="strSql"></param>
/// <returns></returns>
public static string ExcuteSql(string strSql)
{
Database db = DatabaseFactory.CreateDatabase("BusinessDb");
DbCommand cmd = db.GetSqlStringCommand(strSql);
try
{
return db.ExecuteNonQuery(cmd).ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
这3个一局就搞定了 基本所有的需求, 但是有个问题, 存错过程里也是拼接的SQL语句 然后exec执行下。 你们说的SqlParameter 确实很不方便。如果用这个 每个程序员都要根据自己的需求 去复制粘贴参数 赋值。 公司也有 具体的参数
///<summary>
///返回DataView
/// </summary>
/// <param name="strProcName">存储过程名</param>
/// <param name="p">参数数组</param>
/// <returns></returns>
public DataView GetDataView(string strProcName, SqlParameter[] sqlpam)
{
m_strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString();
sqlcon = new SqlConnection(m_strConn);
DataSet dst = new DataSet();
SqlDataAdapter sqlada = new SqlDataAdapter();

if (sqlpam != null)
sqlada.SelectCommand = BuildQueryCommand(strProcName, sqlpam);
else
sqlada.SelectCommand = BuildQueryCommand(strProcName, null);

try
{
if (sqlcon.State == ConnectionState.Open) sqlcon.Close();
sqlcon.Open();
sqlada.SelectCommand.CommandTimeout = 0;
sqlada.Fill(dst);

}
catch (Exception e)
{
throw new Exception(e.Message);
}
finally
{
try
{
sqlcon.Close();
}
catch { }
}
if (dst.Tables.Count > 0)
return dst.Tables[0].DefaultView;
else return null;
}

/// <summary>
/// 建立有参数传送的Command对象
/// </summary>
/// <param name="strProcName">存储过程名</param>
/// <param name="p">参数数组</param>
/// <returns></returns>
private SqlCommand BuildQueryCommand(string strProcName, SqlParameter[] sqlpam)
{
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = strProcName;
sqlcmd.Connection = sqlcon;

if (sqlpam != null)
{
for (int i = 0; i < sqlpam.GetLength(0); i++)
{
sqlcmd.Parameters.Add(sqlpam.GetValue(i));
}
}

return sqlcmd;
}
但是这样 公司的存储过程就没办法模板化 。 比如公司取东西 的存储过程都定义好的, 开发很快。 所有人接手也很快。 只要读懂公司的想法, 所有存储过程拿来就写

存储过程 查询的
新增和修改

删除就不截图了, 跟新增差不多
这么模板化,公司开发任何项目 都很快。 架构搭好, 底层程序员开发很快。 但是唯一缺点就是SQL注入这。 因为存储过程是拼装查询。 你们难道不认为SqlParameter开发起来传参数很墨迹。 尤其在新增的试试, 那参数有的时候好几十列兼职累死,用XML序列号进去就很简单。
X-i-n 2018-03-14
  • 打赏
  • 举报
回复
引用 52 楼 closurer 的回复:
[quote=引用 47 楼 wang2129929 的回复:] 我以前上海的公司就3个方法搞定 所有的存错过程, 取 数据集 public static DataView DisplayDataDetail(string strNo, string strSPName) //参数 , 存错过程命 { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetStoredProcCommand(strSPName); db.AddInParameter(cmd, "chrNo", DbType.String, strNo); DataSet dst = db.ExecuteDataSet(cmd); if (dst != null) { return dst.Tables[0].DefaultView; } else { return null; } } 新增或者修改 public static string SaveDataXML(string strXmlPara, string strSPName) 传进去XML 然后存错过程解析XML 在插入或者修改 { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetStoredProcCommand(strSPName); db.AddInParameter(cmd, "chrXML", DbType.String, strXmlPara); //XML组合文档 db.AddOutParameter(cmd, "chrReturn", DbType.String, 100); try { db.ExecuteNonQuery(cmd); return db.GetParameterValue(cmd, "chrReturn").ToString(); } catch (Exception ex) { return ex.Message; } } /// <summary> /// 执行一条UPDATE、INSERT 或 DELETE 语句 返回影响的行数 /// </summary> /// <param name="strSql"></param> /// <returns></returns> public static string ExcuteSql(string strSql) { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetSqlStringCommand(strSql); try { return db.ExecuteNonQuery(cmd).ToString(); } catch (Exception ex) { return ex.Message; } } 这3个一局就搞定了 基本所有的需求, 但是有个问题, 存错过程里也是拼接的SQL语句 然后exec执行下。 你们说的SqlParameter 确实很不方便。如果用这个 每个程序员都要根据自己的需求 去复制粘贴参数 赋值。 公司也有 具体的参数 ///<summary> ///返回DataView /// </summary> /// <param name="strProcName">存储过程名</param> /// <param name="p">参数数组</param> /// <returns></returns> public DataView GetDataView(string strProcName, SqlParameter[] sqlpam) { m_strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString(); sqlcon = new SqlConnection(m_strConn); DataSet dst = new DataSet(); SqlDataAdapter sqlada = new SqlDataAdapter(); if (sqlpam != null) sqlada.SelectCommand = BuildQueryCommand(strProcName, sqlpam); else sqlada.SelectCommand = BuildQueryCommand(strProcName, null); try { if (sqlcon.State == ConnectionState.Open) sqlcon.Close(); sqlcon.Open(); sqlada.SelectCommand.CommandTimeout = 0; sqlada.Fill(dst); } catch (Exception e) { throw new Exception(e.Message); } finally { try { sqlcon.Close(); } catch { } } if (dst.Tables.Count > 0) return dst.Tables[0].DefaultView; else return null; } /// <summary> /// 建立有参数传送的Command对象 /// </summary> /// <param name="strProcName">存储过程名</param> /// <param name="p">参数数组</param> /// <returns></returns> private SqlCommand BuildQueryCommand(string strProcName, SqlParameter[] sqlpam) { SqlCommand sqlcmd = new SqlCommand(); sqlcmd.CommandType = CommandType.StoredProcedure; sqlcmd.CommandText = strProcName; sqlcmd.Connection = sqlcon; if (sqlpam != null) { for (int i = 0; i < sqlpam.GetLength(0); i++) { sqlcmd.Parameters.Add(sqlpam.GetValue(i)); } } return sqlcmd; } 但是这样 公司的存储过程就没办法模板化 。 比如公司取东西 的存储过程都定义好的, 开发很快。 所有人接手也很快。 只要读懂公司的想法, 所有存储过程拿来就写 存储过程 查询的 新增和修改 。 删除就不截图了, 跟新增差不多 这么模板化,公司开发任何项目 都很快。 架构搭好, 底层程序员开发很快。 但是唯一缺点就是SQL注入这。 因为存储过程是拼装查询。 你们难道不认为SqlParameter开发起来传参数很墨迹。 尤其在新增的试试, 那参数有的时候好几十列兼职累死,用XML序列号进去就很简单。
SqlParameter 的确很麻烦,不封装一下,没人愿意用的。 回到你的问题上去,拼接如何防止注入攻击,除了替换单引号,整个帖子,没有人提出其他意见。 [/quote] base64编码字段值或者所有字段blob就行啊,但是这么处理比参数化查询要折腾得多吧
闭包客 2018-03-14
  • 打赏
  • 举报
回复
引用 47 楼 wang2129929 的回复:
我以前上海的公司就3个方法搞定 所有的存错过程, 取 数据集 public static DataView DisplayDataDetail(string strNo, string strSPName) //参数 , 存错过程命 { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetStoredProcCommand(strSPName); db.AddInParameter(cmd, "chrNo", DbType.String, strNo); DataSet dst = db.ExecuteDataSet(cmd); if (dst != null) { return dst.Tables[0].DefaultView; } else { return null; } } 新增或者修改 public static string SaveDataXML(string strXmlPara, string strSPName) 传进去XML 然后存错过程解析XML 在插入或者修改 { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetStoredProcCommand(strSPName); db.AddInParameter(cmd, "chrXML", DbType.String, strXmlPara); //XML组合文档 db.AddOutParameter(cmd, "chrReturn", DbType.String, 100); try { db.ExecuteNonQuery(cmd); return db.GetParameterValue(cmd, "chrReturn").ToString(); } catch (Exception ex) { return ex.Message; } } /// <summary> /// 执行一条UPDATE、INSERT 或 DELETE 语句 返回影响的行数 /// </summary> /// <param name="strSql"></param> /// <returns></returns> public static string ExcuteSql(string strSql) { Database db = DatabaseFactory.CreateDatabase("BusinessDb"); DbCommand cmd = db.GetSqlStringCommand(strSql); try { return db.ExecuteNonQuery(cmd).ToString(); } catch (Exception ex) { return ex.Message; } } 这3个一局就搞定了 基本所有的需求, 但是有个问题, 存错过程里也是拼接的SQL语句 然后exec执行下。 你们说的SqlParameter 确实很不方便。如果用这个 每个程序员都要根据自己的需求 去复制粘贴参数 赋值。 公司也有 具体的参数 ///<summary> ///返回DataView /// </summary> /// <param name="strProcName">存储过程名</param> /// <param name="p">参数数组</param> /// <returns></returns> public DataView GetDataView(string strProcName, SqlParameter[] sqlpam) { m_strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString(); sqlcon = new SqlConnection(m_strConn); DataSet dst = new DataSet(); SqlDataAdapter sqlada = new SqlDataAdapter(); if (sqlpam != null) sqlada.SelectCommand = BuildQueryCommand(strProcName, sqlpam); else sqlada.SelectCommand = BuildQueryCommand(strProcName, null); try { if (sqlcon.State == ConnectionState.Open) sqlcon.Close(); sqlcon.Open(); sqlada.SelectCommand.CommandTimeout = 0; sqlada.Fill(dst); } catch (Exception e) { throw new Exception(e.Message); } finally { try { sqlcon.Close(); } catch { } } if (dst.Tables.Count > 0) return dst.Tables[0].DefaultView; else return null; } /// <summary> /// 建立有参数传送的Command对象 /// </summary> /// <param name="strProcName">存储过程名</param> /// <param name="p">参数数组</param> /// <returns></returns> private SqlCommand BuildQueryCommand(string strProcName, SqlParameter[] sqlpam) { SqlCommand sqlcmd = new SqlCommand(); sqlcmd.CommandType = CommandType.StoredProcedure; sqlcmd.CommandText = strProcName; sqlcmd.Connection = sqlcon; if (sqlpam != null) { for (int i = 0; i < sqlpam.GetLength(0); i++) { sqlcmd.Parameters.Add(sqlpam.GetValue(i)); } } return sqlcmd; } 但是这样 公司的存储过程就没办法模板化 。 比如公司取东西 的存储过程都定义好的, 开发很快。 所有人接手也很快。 只要读懂公司的想法, 所有存储过程拿来就写 存储过程 查询的 新增和修改 。 删除就不截图了, 跟新增差不多 这么模板化,公司开发任何项目 都很快。 架构搭好, 底层程序员开发很快。 但是唯一缺点就是SQL注入这。 因为存储过程是拼装查询。 你们难道不认为SqlParameter开发起来传参数很墨迹。 尤其在新增的试试, 那参数有的时候好几十列兼职累死,用XML序列号进去就很简单。
SqlParameter 的确很麻烦,不封装一下,没人愿意用的。 回到你的问题上去,拼接如何防止注入攻击,除了替换单引号,整个帖子,没有人提出其他意见。
  • 打赏
  • 举报
回复
引用 15 楼 closurer 的回复:
拼接 SQL 的问题之所以还有人在用,就是因为简单易上手,而参数化查询的代码比较啰嗦。 我写了一个模块是兼顾两者的优点的。
看下47楼的留言, 这就是公司底层供所有程序员调用的 连接数据库
  • 打赏
  • 举报
回复
引用 44 楼 sp1234 的回复:
单就写一个 sql 语句来说,我们的要求是,一个程序员起码要懂得 Replace("'","'') 这个知识。别的先不多说,先说说看 t-sql 语言代码中的字符串常量应该如何写的基本语法知识。如果这个时候一个程序员来“扯”说应该过滤什么sql关键字,那么岂不是根本就在抄一些概念而没有掌握真正的 t-sql 语法知识了嘛。
看下47楼的留言呗。 这就是我公司现在底层供所有人调用的
  • 打赏
  • 举报
回复
引用 48 楼 nitaiyoucala 的回复:
用参数来。存储过程传参
你在说什么?
nitaiyoucala 2018-03-14
  • 打赏
  • 举报
回复
用参数来。存储过程传参
闭包客 2018-03-09
  • 打赏
  • 举报
回复
引用 43 楼 sp1234 的回复:
在我们的系统中,封装了这种 SetParam 方法,例如可能写
var tableExists = tran.CreateCommand($"select Id from MasterSlave where Id={Common.Extensions.Prefix}id and Child={Common.Extensions.Prefix}child")
    .SetParam("id", parentTableName)
    .SetParam("child", propName)
    .ExecuteAny();
if (!tableExists)
这种 SetParam 函数可以连缀书写,然后直接连缀地查询出单个对象、集合对象或者 ExecuteAny 之类的。 并且你可以看到,我们的 sql 语句考虑到同时适配 SQL Server、Oracle、MySql 等 sql 的不同语法,所以我们才用 SqlHelper。 如果你就是简单的 SQL Server 语法拼接字符串 sql,那么其实原来怎么拼接字符串还怎么拼接,不是着急要改为参数化写法。因为等你需要 SqlHelper 化的时候,还需要再重新写。
这种 SetParam 的链式语法设计相当的糟糕,如果有 10 个参数,就要写 10 次……
闭包客 2018-03-09
  • 打赏
  • 举报
回复
引用 42 楼 sp1234 的回复:
我们的程序基本上都是参数sql查询,比如说我们写
using (var conn = Common.Extensions.ConnectDB())
{
    var cmd = conn.CreateCommand();
    cmd.CommandText = $"select max({Common.Extensions.LB}LiuShuiHao{Common.Extensions.RB}) from {Common.Extensions.LB}Flow++JL901_N1{Common.Extensions.RB} " +
        $"where {Common.Extensions.LB}LiuShuiHao{Common.Extensions.RB}>={Common.Extensions.Prefix}b1 and {Common.Extensions.LB}LiuShuiHao{Common.Extensions.RB}<={Common.Extensions.Prefix}b2";   //数据库差异,所以不用 between
    var nw = DateTime.Now.ToString("yyyyMMdd");
    cmd.SetParam("b1", long.Parse(nw + "001"));
    cmd.SetParam("b2", long.Parse(nw + "999"));
    var rn = cmd.ExecuteScalar();
    ................
不过,这并不影响你对于字符串拼接方式写 sql 的知识。如果你原本的字符串拼接的不复杂,那么测试一下,或者人工走查一下有没有写上
Replace(...,....)
代码,这个也是已经很方便了,一般来说不用改为复杂的写法。
这种加上了大段花括号内容的 SQL 语句已经面目全非,难以卒读了,很难相信你还会觉得这【很方便】。
by_封爱 2018-03-08
  • 打赏
  • 举报
回复
谁会闲的注入你的内部系统...干吧 哈哈
zhanglong_longlong 2018-03-08
  • 打赏
  • 举报
回复
参数化/...
  • 打赏
  • 举报
回复
单就写一个 sql 语句来说,我们的要求是,一个程序员起码要懂得 Replace("'","'') 这个知识。别的先不多说,先说说看 t-sql 语言代码中的字符串常量应该如何写的基本语法知识。如果这个时候一个程序员来“扯”说应该过滤什么sql关键字,那么岂不是根本就在抄一些概念而没有掌握真正的 t-sql 语法知识了嘛。
  • 打赏
  • 举报
回复
在我们的系统中,封装了这种 SetParam 方法,例如可能写
var tableExists = tran.CreateCommand($"select Id from MasterSlave where Id={Common.Extensions.Prefix}id and Child={Common.Extensions.Prefix}child")
    .SetParam("id", parentTableName)
    .SetParam("child", propName)
    .ExecuteAny();
if (!tableExists)
这种 SetParam 函数可以连缀书写,然后直接连缀地查询出单个对象、集合对象或者 ExecuteAny 之类的。 并且你可以看到,我们的 sql 语句考虑到同时适配 SQL Server、Oracle、MySql 等 sql 的不同语法,所以我们才用 SqlHelper。 如果你就是简单的 SQL Server 语法拼接字符串 sql,那么其实原来怎么拼接字符串还怎么拼接,不是着急要改为参数化写法。因为等你需要 SqlHelper 化的时候,还需要再重新写。
加载更多回复(33)

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧