.net配合SQL快速开发优点和缺点(SQL注入)讨论

好奇都是要学的 2018-03-14 12:12:36
我以前上海的公司就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;
}
}
执行一条UPDATE、INSERT 或 DELETE 语句 返回影响的行数
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 确实很不方便。如果用这个 每个程序员都要根据自己的需求 去复制粘贴参数 赋值。 公司也有 具体的使用,但是基本没什么人用的
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;
}
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注入这。 因为存储过程是拼装查询。而且还可以分出一个人就写SQL存储过程基本的增删改查。 如果用SqlParamete配合最后一个方法开发起来传参数很墨迹。 尤其在新增的时候, 那参数有的时候好几十列简直累死,用XML序列号进去就很简单。新手用SqlParamete上手也慢。 也不好分一个人就写存储过程。
希望大家结合这来聊聊针对主要的开发模式优缺点, 和怎么避免SQL注入
...全文
1383 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 33 楼 wanghui0380 的回复:
3年以后在看吧。你现在的状态就和博客园6年前“吉日嘎啦”带起来的那波一样。没啥好说的。等你3年后再来讨论问题,现在么你的想法是我要成下一个“吉日"
http://weixin.zsplaying.com/ 这是后台 前台有提前预约,支付,投票、商城、积分 这个平台如果你们开发要多钱!。 报表是随意 加的。 账号admin 密码1 你看下这个项目如果你做要多少钱, 前台 有微信公众号内展示, APP展示。 没有PC前端
  • 打赏
  • 举报
回复
引用 33 楼 wanghui0380 的回复:
3年以后在看吧。你现在的状态就和博客园6年前“吉日嘎啦”带起来的那波一样。没啥好说的。等你3年后再来讨论问题,现在么你的想法是我要成下一个“吉日"
这个项目到不了你说的那样, 这个是定制开发。 开发完 就完事了。 没有新的需求不会再动了
wanghui0380 2018-03-19
  • 打赏
  • 举报
回复
3年以后在看吧。你现在的状态就和博客园6年前“吉日嘎啦”带起来的那波一样。没啥好说的。等你3年后再来讨论问题,现在么你的想法是我要成下一个“吉日"
  • 打赏
  • 举报
回复
引用 29 楼 sp1234 的回复:
如果你问我这类问题如何能抄一堆代码就能提高软件开发水平,我说“不可能有答案”。因为这类问题就是在底层一些小问题上反复纠结,技术讨论得再多也不过是增删改查索引之类的,根本从这类问题上只能看出一些类似 SQLHelper 函数之类的分享,而软件项目、产品的设计开发有 90% 内容在于更高层的知识。
我的技术应该是停止了, 最新的好多新封装方法我压根就不知道。 因为我已经停止了, 我在这片土壤连个交流的人都没有。 除非我回到北京。 进入团对或者自己在家买书看,但我现在主要开发是游戏开发c++ 加LUA, 开发手游。 写写斗地主,跑得快 麻将, 填大坑,扎金花 510K什么的。 根本没有经历去看C#了。 公司什么接个小活就干小活, 越快完成越好。
  • 打赏
  • 举报
回复
引用 26 楼 sp1234 的回复:
软件最实际的功能在于丰富的业务处理,如果你满脑子只有一些基本字段、属性的增删改查,那么你没有真正写明复杂的业务处理的框架。这就好像满脑子都认为盖高楼大厦其实就是堆砖头和管子的建筑小工,是不能理解建筑师的技术要求的。你的精力全都用到c#不写代码、而存储过程写代码这个角度来了,看似高大上地全都是围绕技术,而实际上根本没有用主流技术来落实到业务领域处理中,一直在纠结技术。 等这种东西一旦落地,才显出其多余来了。如果你从业务领域设计出发,你要写的sql一点都没少,而且你丧失了 c#、.net 领域的各种面向对象设计和前端各种框架的考虑,耗费全部时间完全就是在那里纠结底层数据保存问题呢。
我的业务设计感觉还行。 10年开发经验写了7年的.NET开发, 上海北京也都是大公司。 只是回到老家后发现软件根本没有用武之地。 至于存储过程是我上海项目经理认可的。我跟他干的久习惯了他的方式。 他的意思是, 存储过程执行快。 如果因为SQL错误导致的问题, 可以不编译代码 直接改存储过程修复。 但是我北京公司压根就不用存储过程。全是SQL语句写在代码里。
  • 打赏
  • 举报
回复
http://weixin.zsplaying.com/ 这是后台 前台有提前预约,支付,投票、商城、积分 这个平台如果你们开发要多钱!。 报表是随意 加的。
  • 打赏
  • 举报
回复
如果你问我这类问题如何能抄一堆代码就能提高软件开发水平,我说“不可能有答案”。因为这类问题就是在底层一些小问题上反复纠结,技术讨论得再多也不过是增删改查索引之类的,根本从这类问题上只能看出一些类似 SQLHelper 函数之类的分享,而软件项目、产品的设计开发有 90% 内容在于更高层的知识。
  • 打赏
  • 举报
回复
引用 26 楼 sp1234 的回复:
软件最实际的功能在于丰富的业务处理,如果你满脑子只有一些基本字段、属性的增删改查,那么你没有真正写明复杂的业务处理的框架。这就好像满脑子都认为盖高楼大厦其实就是堆砖头和管子的建筑小工,是不能理解建筑师的技术要求的。你的精力全都用到c#不写代码、而存储过程写代码这个角度来了,看似高大上地全都是围绕技术,而实际上根本没有用主流技术来落实到业务领域处理中,一直在纠结技术。 等这种东西一旦落地,才显出其多余来了。如果你从业务领域设计出发,你要写的sql一点都没少,而且你丧失了 c#、.net 领域的各种面向对象设计和前端各种框架的考虑,耗费全部时间完全就是在那里纠结底层数据保存问题呢。
你说的我懂, 我上海2年,北京2年, 大连1年, 哈尔滨2年, 现在这2年我回到了黑龙江齐齐哈尔一直写服务端和LUA开发。 棋牌类房卡模式游戏开发。我也想进步,也想前进。 但是我连个交流人没有。我就是在吃老本。 在我公司如果我不会了, 那全公司都没有会的了、 我也想过回北京,但是拖家带口的去北京也不好弄。 我这个城市软件公司都不会超过5个, 我在这个4线城市就算比较厉害的了。现在月薪20K还是没白天黑夜学习游戏开发得了,如果就是C# 开发, 我们这地方也就1500左右的工资。我想自己成立公司又没团队。 在这片土壤我连个伙伴都找不到。我只能靠自己去尽快完成公司的任务。 公司说做什么马上就得接触去做,根本没有系统没有职务。用哪干哪。 给你看个网站, 这个是我一个人独立开发的, 前台CSS不是我弄的 http://weixin.zsplaying.com/ 完全我一个人用了小半年时间做的。 他这个还有前台预定,支付,投票、商城、积分我就不发链接了。 这个后台业务就够看了。
  • 打赏
  • 举报
回复
引用 24 楼 wang2129929 的回复:
[quote=引用 11 楼 wanghui0380 的回复:] 所以最终的情况是,项目经过3年以后,存储过程过千个,谁也不知道这些存储过程到底干了啥,你项目部的人只知道自己手上常用的那么30个存储过程 谁也不敢删除,修改,这些东西。项目资料完全一塌糊涂,大家跳槽后,后面接手的人一看,这NM几千存储过程,到底谁是谁来着?拉倒,俺重做把,重做都比梳理这几千个存储过程来的容易
你说的不会存在的, 一个程序员 在写的时候, 比如表明是 USERS, 那他要取这个表 首先要用下usersget 如果不存在 才会自己写,如果存在 就不用写了, 如果缺少他需要的东西,他会在这个存储过程上累加 他要的列, 但是原有列不变。 但是大多数都不用加了。 就跟上面我们的标题一样, 谁在什么时候改过这个存储过程 都要标示的。公司所有人都按照这个流程走。 现在开发起来确实挺快[/quote] 如果要读取一个 User 对象,那么调用
public static GetUser(string id)
{  
      ......
}
方法就行了,自然是只写一次,然后反复调用。 关键是,这值得纠结于“存储过程”吗? 复用 c# 方法代码不好吗?为什么要硬性规定必须是存储过程?这其实只是偏爱存储过程的结果,并没有什么别的理由。 其实有经验的大公司为了高效率地开发,是去掉存储过程思路的,使用关系数据库作为数据持久化、索引的工具,而不用其存储过程部分。
  • 打赏
  • 举报
回复
软件最实际的功能在于丰富的业务处理,如果你满脑子只有一些基本字段、属性的增删改查,那么你没有真正写明复杂的业务处理的框架。这就好像满脑子都认为盖高楼大厦其实就是堆砖头和管子的建筑小工,是不能理解建筑师的技术要求的。你的精力全都用到c#不写代码、而存储过程写代码这个角度来了,看似高大上地全都是围绕技术,而实际上根本没有用主流技术来落实到业务领域处理中,一直在纠结技术。 等这种东西一旦落地,才显出其多余来了。如果你从业务领域设计出发,你要写的sql一点都没少,而且你丧失了 c#、.net 领域的各种面向对象设计和前端各种框架的考虑,耗费全部时间完全就是在那里纠结底层数据保存问题呢。
  • 打赏
  • 举报
回复
引用 17 楼 hemowolf 的回复:
楼主的这类模式以前曾经也用到过 不过,我最喜欢的还是用ORM框架 楼主的模式说白了还是用底层的ADO.net访问数据库,它的优点就是简单,直观,直接与数据库交互。适合小型项目开发。 但缺点是,无法利用编译器进行查错。以前经常遇到的坑就是,数据表设计不规范,或者某人违反了规范,比如有个字段,叫XXXXXNo,有的人会命名为 XXXXXNum、XXXXXSn……,或者在数据库里是规范的,结果写存储过程时,又通过 As 子句把结果集的字段名改了。这时系统整合编译没问题,只有在测试时程序运行到这里才会发现错误,而测试时有可能这段代码可能没有被执行到,于是雷就被埋下来了。这种麻烦在进行增加、修改表字段时也都会遇到。如果项目大一点,你需要进对所有的代码全部扫描一次,费力气,而且还会有遗漏。而用 orm 框架则基本上靠框架生成实体类,然后通过编译器能够立刻找到哪些地方需要修改。
实体类映射 我们也用过, 项目嵌入不即使 就会导致2个人 写了2个 映射类, 然后对应一个表。 很麻烦。 然后取的东西不同 ,还得重新起个映射类, 因为关联表不一定也一样, 这种我觉得就取某个表的所有挺好用的。大家都可以用一个类
  • 打赏
  • 举报
回复
引用 11 楼 wanghui0380 的回复:
所以最终的情况是,项目经过3年以后,存储过程过千个,谁也不知道这些存储过程到底干了啥,你项目部的人只知道自己手上常用的那么30个存储过程 谁也不敢删除,修改,这些东西。项目资料完全一塌糊涂,大家跳槽后,后面接手的人一看,这NM几千存储过程,到底谁是谁来着?拉倒,俺重做把,重做都比梳理这几千个存储过程来的容易
你说的不会存在的, 一个程序员 在写的时候, 比如表明是 USERS, 那他要取这个表 首先要用下usersget 如果不存在 才会自己写,如果存在 就不用写了, 如果缺少他需要的东西,他会在这个存储过程上累加 他要的列, 但是原有列不变。 但是大多数都不用加了。 就跟上面我们的标题一样, 谁在什么时候改过这个存储过程 都要标示的。公司所有人都按照这个流程走。 现在开发起来确实挺快
吉普赛的歌 2018-03-15
  • 打赏
  • 举报
回复
引用 18 楼 hemowolf 的回复:
这个写法效率低吗? 我感觉不低! 数据库系统会有优化不说,另外,所有的 And 中都是先判断参数是否为空,利用了条件判断的短路原理:在or条件判断中,如果前一个条件成立,则后一个逻辑判断会自动忽略。 最好,就算效率低,相比 sql 注入漏洞而言,这个代价是值得的
低不低不是你一句话, 是要看实际的执行计划, 这咱写法根本用不到索引。 为什么要牺牲效率? 为什么不想既安全又执行效率高的办法?
吉普赛的歌 2018-03-15
  • 打赏
  • 举报
回复
引用 18 楼 hemowolf 的回复:
你这种SQL写法效率很低的了, 大数据量根本不能用
这个写法效率低吗? 我感觉不低! 数据库系统会有优化不说,另外,所有的 And 中都是先判断参数是否为空,利用了条件判断的短路原理:在or条件判断中,如果前一个条件成立,则后一个逻辑判断会自动忽略。 最好,就算效率低,相比 sql 注入漏洞而言,这个代价是值得的[/quote] 低不低不是你一句话, 是要看实际的执行计划, 这咱写法根本用不到索引。 为什么要牺牲效率? 为什么不想既安全又执行效率高的办法?
Caeser1248 2018-03-15
  • 打赏
  • 举报
回复
厉害厉害 虽然看不懂
小灰狼 2018-03-15
  • 打赏
  • 举报
回复
引用 16 楼 yenange 的回复:
[quote=引用 15 楼 hemowolf 的回复:] 尽量不要去拼 sql,会很麻烦,SQL注入漏洞的根源就在这里 对于查询的存储过程,可以这样写 假设有个表 Bill( Id int primary key, -- 主键 No varchar(100), 单号 CreateDateTime DateTime -- 创建时间 ...... -- 其它字段省略 )

Alter Proc ActivityGet
  @strNo Varchar(100) = null, -- 要查询的单号
  @dtMinCreateDateTime DateTime = null,  -- 最早创建时间
  @dtMaxCreateDateTime DateTime = null -- 最晚创建时间
As 
Begin 
  Select * From Bill 
  Where 
    (@strNo Is Null Or No = @strNo)
    And (@dtMinCreatedDateTime Is Null Or CreatedDateTime >= @dtMinCreatedDateTime)
    And (@dtMaxCreatedDateTime Is Null Or CreateddateTime <= @dtMaxCreatedDateTime)
End 
这样写避免拼接 sql 语句,但是要把可能的查询条件全部展示到存储过程的参数里,如果不想根据某个参数条件查询,则把那个参数赋空值 C#好多年不用了,不过,我记得 C# 好象有语法现象可以支持缺省参数不用传的情况
你这种SQL写法效率很低的了, 大数据量根本不能用[/quote] 这个写法效率低吗? 我感觉不低! 数据库系统会有优化不说,另外,所有的 And 中都是先判断参数是否为空,利用了条件判断的短路原理:在or条件判断中,如果前一个条件成立,则后一个逻辑判断会自动忽略。 最好,就算效率低,相比 sql 注入漏洞而言,这个代价是值得的
小灰狼 2018-03-15
  • 打赏
  • 举报
回复
楼主的这类模式以前曾经也用到过 不过,我最喜欢的还是用ORM框架 楼主的模式说白了还是用底层的ADO.net访问数据库,它的优点就是简单,直观,直接与数据库交互。适合小型项目开发。 但缺点是,无法利用编译器进行查错。以前经常遇到的坑就是,数据表设计不规范,或者某人违反了规范,比如有个字段,叫XXXXXNo,有的人会命名为 XXXXXNum、XXXXXSn……,或者在数据库里是规范的,结果写存储过程时,又通过 As 子句把结果集的字段名改了。这时系统整合编译没问题,只有在测试时程序运行到这里才会发现错误,而测试时有可能这段代码可能没有被执行到,于是雷就被埋下来了。这种麻烦在进行增加、修改表字段时也都会遇到。如果项目大一点,你需要进对所有的代码全部扫描一次,费力气,而且还会有遗漏。而用 orm 框架则基本上靠框架生成实体类,然后通过编译器能够立刻找到哪些地方需要修改。
吉普赛的歌 2018-03-15
  • 打赏
  • 举报
回复
引用 15 楼 hemowolf 的回复:
尽量不要去拼 sql,会很麻烦,SQL注入漏洞的根源就在这里 对于查询的存储过程,可以这样写 假设有个表 Bill( Id int primary key, -- 主键 No varchar(100), 单号 CreateDateTime DateTime -- 创建时间 ...... -- 其它字段省略 )

Alter Proc ActivityGet
  @strNo Varchar(100) = null, -- 要查询的单号
  @dtMinCreateDateTime DateTime = null,  -- 最早创建时间
  @dtMaxCreateDateTime DateTime = null -- 最晚创建时间
As 
Begin 
  Select * From Bill 
  Where 
    (@strNo Is Null Or No = @strNo)
    And (@dtMinCreatedDateTime Is Null Or CreatedDateTime >= @dtMinCreatedDateTime)
    And (@dtMaxCreatedDateTime Is Null Or CreateddateTime <= @dtMaxCreatedDateTime)
End 
这样写避免拼接 sql 语句,但是要把可能的查询条件全部展示到存储过程的参数里,如果不想根据某个参数条件查询,则把那个参数赋空值 C#好多年不用了,不过,我记得 C# 好象有语法现象可以支持缺省参数不用传的情况
你这种SQL写法效率很低的了, 大数据量根本不能用
小灰狼 2018-03-15
  • 打赏
  • 举报
回复
尽量不要去拼 sql,会很麻烦,SQL注入漏洞的根源就在这里 对于查询的存储过程,可以这样写 假设有个表 Bill( Id int primary key, -- 主键 No varchar(100), 单号 CreateDateTime DateTime -- 创建时间 ...... -- 其它字段省略 )

Alter Proc ActivityGet
  @strNo Varchar(100) = null, -- 要查询的单号
  @dtMinCreateDateTime DateTime = null,  -- 最早创建时间
  @dtMaxCreateDateTime DateTime = null -- 最晚创建时间
As 
Begin 
  Select * From Bill 
  Where 
    (@strNo Is Null Or No = @strNo)
    And (@dtMinCreatedDateTime Is Null Or CreatedDateTime >= @dtMinCreatedDateTime)
    And (@dtMaxCreatedDateTime Is Null Or CreateddateTime <= @dtMaxCreatedDateTime)
End 
这样写避免拼接 sql 语句,但是要把可能的查询条件全部展示到存储过程的参数里,如果不想根据某个参数条件查询,则把那个参数赋空值 C#好多年不用了,不过,我记得 C# 好象有语法现象可以支持缺省参数不用传的情况
爱此清夜雨 2018-03-15
  • 打赏
  • 举报
回复
用orm实现大部分增删改,少数需求用存储过程
加载更多回复(14)

62,074

社区成员

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

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

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

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