1.前言

相比高级语言的调试如C# , 调试SQL是件痛苦的事 . 特别是那些上千行的存储过程, 更是我等码农的噩梦.

在将上千行存储过程的SQL 分解到 C# 管理后, 也存在调试的不通畅, 如何让调试流畅些呢, 请看后续

2.常见调试

2.1 通常在Dapper 里面一个断点下去, 抓到类似如下SQL:

 
 
1
2
3
4
5
6
7
SELECT
a.*
FROM  dbo.ptype a
INNER JOIN dbo.PType_Price b ON a.typeId=b.PTypeID
LEFT JOIN dbo.PType_Units c ON a.typeId=c.UnitsId
WHERE a.typeId=@typeid AND a.CreateDate=@Area
AND preprice1=@preprice1 AND deleted=@deleted

各种@符号, 需要手工替换后才能调试(麻烦), 要是能抓到最终SQL就好了

2.2 庆幸的是可以通过SQLServer Profiler 来抓到最终SQL

但是生产环境中的SQLServer,  并发执行的SQL 非常多, 如上图所见, 在一大堆SQL 里面找到你刚才执行的SQL也比较麻烦, 即使可以Ctrl + F 调出搜索框来搜索, 也要想个好的关键字来搜索 , 麻烦.

3.解决方案

既然我们想要最终的SQL , 为毛不在丢给Dapper 执行前, 就已经是最终SQL了呢, 上工具代码:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class SqlHelper
    {
 
        public Dictionary<string, object> Param = new Dictionary<string, object>();
 
        public string ReplaceParam(ref string sql)
        {
            if (Param.Count == 0)
            {
                return sql;
            }
 
            StringBuilder sb = new StringBuilder();
            sb.Append(sql);
            foreach (var item in Param)
            {
                var paramName = item.Key;
                var paramValue = item.Value;
                var type = paramValue.GetType();
                if (type == typeof(string) || type == typeof(DateTime))
                {
                    //字符串
                    sb.Replace($"@{paramName}", $"'{paramValue}'");
                }
                else if (type == typeof(bool))
                {
                    //bool 类型
                    if (paramValue.ToString() == "True")
                    {
 
                        sb.Replace($"@{paramName}", "1");
                    }
                    else
                    {
                        sb.Replace($"@{paramName}", "0");
                    }
                }
                else
                {
                    //数值
                    sb.Replace($"@{paramName}", paramValue.ToString());
                }
            }
 
            sql = sb.ToString();
            return sql;
        }
    }

调用示例:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public IEnumerable<Ptype> GetPtypeDetail()
        {
            var sql = @"
SELECT a.*
FROM  dbo.ptype a
INNER JOIN dbo.PType_Price b ON a.typeId=b.PTypeID
LEFT JOIN dbo.PType_Units c ON a.typeId=c.UnitsId
WHERE a.typeId=@Typeid AND a.CreateDate=@CreateDate
AND preprice1=@preprice1 AND deleted=@deleted
 
";
            var sqlHelper = new SqlHelper();
 
            sqlHelper.Param.Add("Typeid", "001");
            sqlHelper.Param.Add("CreateDate", DateTime.Now);
            sqlHelper.Param.Add("preprice1", 3.62M);
            sqlHelper.Param.Add("deleted", true);
            sqlHelper.ReplaceParam(ref sql);
 
            IEnumerable<Ptype> plist = new List<Ptype>();
            using (var con = SQLServerHelper.GetConnection())
            {
                plist = con.Query<Ptype>(sql);
            }
 
            return plist;
        }

这样丢给Dapper 执行的SQL 始终是最终SQL, 就不用煞费苦心去抓了.

PS: 有人可能会质疑这样替换的效率,不用担心已测试 , C#的字符串替换是非常快的, 上面的调用实例, 当时的测试结果是 微妙和纳秒级别, 有兴趣的看管可以再测试.

4. 最后

现在丢给Dapper执行的不再是 充满@参数的SQL ,  而是一个替换好的最终SQL .

这样当老板隔老远吼道你说: 小蒋, 你tm 有个XX bug ,赶紧看看 .

你可以不慌不忙的在 Dapper Query处打个断点

鼠标放在SQL变量上, 轻松的拿到最终SQL进行调试, 而不是, 手动去替换@参数, 又或则在SQLServer Profiler 里面大海捞针了!!!

写出易于调试的SQL的更多相关文章

  1. 写出易调试的SQL(修订版)

    h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...

  2. 写出易调试的SQL

    h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...

  3. 写出易调试的SQL—西科软件

    1.前言 上篇 写出易调试的SQL , 带来了一些讨论, 暴露了不能重用执行计划和sql注入问题, 十分感谢园友们的建议 . 经过调整后 ,将原来的SQLHelper 抓SQL 用做调试环境用, 发布 ...

  4. 如何写出性能好的sql

    开发人员是很少注意SQL对数据库性能影响的重要性的,大多程序员都会认为SQL是比较简单的,需要的时候查查手册就可以了,很少有深究的. 这样的观念对大型系统的开发是致命的,需要纠正这样的观念. 造成这样 ...

  5. Mysql写出高质量的sql语句的几点建议

    CleverCode在实际的工作也写过一些低效率的sql语句.这些语句会给数据库带来非常大的压力.最基本的表现就是sql语句执行慢,后来逐渐的去优化和尝试. 总结了一些高质量的sql语句的写法.这里C ...

  6. Oracle 如何写出高效的 SQL

    转自:Oracle 如何写出高效的 SQL 要想写出高效的SQL 语句需要掌握一些基本原则,如果你违反了这些原则,一般情况下SQL 的性能将会很差. 1. 减少数据库访问次数连接数据库是非常耗时的,虽 ...

  7. SQL SERVER全面优化-------写出好语句是习惯

    前几篇文章已经从整体提供了诊断数据库的各个方面问题的基本思路...也许对你很有用,也许你觉得离自己太远.那么今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的 ...

  8. Oracle如何写出高效的SQL

    转载:http://www.blogjava.net/ashutc/archive/2009/07/19/277215.html 1.选择最有效率的表明顺序(只在基于规则的优化器中有效) Oracle ...

  9. [转]如何写出高效能TSQL -深入浅出SQL Server Relational Engine (含 SQL 2014 in-memory Engine)

    [转]如何写出高效能TSQL -深入浅出SQL Server Relational Engine (含 SQL 2014 in-memory Engine) http://blogs.technet. ...

随机推荐

  1. web自动化1-selenium简介及环境搭建

    selenium 开源软件 支持多浏览器Firefox.Chrome.IE 跨平台Windows.Mac.Linux 多语言 java python Ruby php js 对web支持好,多种API ...

  2. JS表单对象和图片对象--JavaScript基础

    1.表单对象 1)访问者输入正确的密码才可进入网站 HTML DOM prompt() 方法,prompt() 方法用于显示可提示用户进行输入的对话框.prompt(text,defaultText) ...

  3. 关于ng-options

    在实际使用过程中对angular的ng-options指令有点不解,有的时候觉得很容易理解和上手,但其实等到遇到问题时,发现它很是生疏,(key,value)键值对获取,as关键词,track by ...

  4. 原创:TSP问题解决方案-----禁忌搜索算法C实现

    本文着重于算法的实现,对于理论部分可自行查看有关资料可以简略参考该博文:http://blog.csdn.net/u013007900/article/details/50379135 本文代码部分基 ...

  5. poj1006中国剩余定理

    Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 103506   Accepted: 31995 Des ...

  6. jvm的垃圾回收算法

    一.对象存活判断判断对象是否存活一般有两种方式:1.引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.2 ...

  7. Python实战之set学习笔记及简单练习

    ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__' ...

  8. 有关 Hybrid 开发模式实践总结

    前言 随着公司业务不断发展,移动开发项目越来越多,项目任务时间紧,我们内部开发流程是以项目为导向,有别于一般公司对产品不断迭代的做法,但移动端开发人员资源有限,需要在不同项目之间做业务场景切换开发,就 ...

  9. ORALCE PL/SQL学习笔记

    ORALCE  PL/SQL学习笔记 详情见自己电脑的备份数据资料

  10. C#微信公众号/订阅号开发 接口源码

    using System; using System.Web; using System.IO; using System.Text; using System.Web.Security; using ...