[数据库] SqlServer学习总结

426 0
Honkers 2026-3-23 20:48:30 来自手机 | 显示全部楼层 |阅读模式

目录

1.SqlServer基础

一、数据库核心概念

二、SQL 语句核心分类与用法

数据定义语言(DDL)

2.查询SQL

数据查询语言(DQL)核心语法

完整性约束类型

DQL执行顺序逻辑

3.多表联查

联合查询

连接查询

子查询

SQL Server系统函数

数值型函数

字符串函数

日期和时间函数

流程控制函数

注意事项

核心思想

ADO编程

数据库连接(SqlConnection/MySqlConnection)

ADO 数据库连接方法

数据库操作实现

执行SQL命令方式

数据解析方案

断开式数据访问(DataSet + SqlDataAdapter)

事务(SqlTransaction)

封装(DBHelper)

核心思想

1.SqlServer基础

一、数据库核心概念

  1. 数据库本质:临时存储的数据,如使用变量,集合,数组这种方式存放数据,属于临时存储,程序结束就被释放出去了,而使用数据库存储可以使得数据存储在在硬盘,第三方存储介质中,对数据统计, 提供了安全性,还方便我们进行查找等
     
  2. 核心层级关系:关系型数据库管理系统(RDBMS)包含多个数据库,每个数据库由多张表组成;表分为表结构(列名 + 列类型)和表记录(行数据)两部分。
     
  3. 常见数据库

    1>Oracle(神喻):甲骨文(最高!); 商业产品, 不开源, 收费(服务费), 金融行业
    2>DB2:IBM; 收费
    3>SQL Server:微软; 收费 C#
    4>MySQL:甲骨文;中小型公司: 5.7以及之前: 开源组织, 开源免费 8.0之后的版本, 甲骨文收购, 专业版收费
    (C#学习阶段使用SQL Server方便连接)

二、SQL 语句核心分类与用法

数据定义语言(DDL)

  • 数据库操作
    • 查看所有数据库:SELECT name FROM sys.databases;。
    • 切换数据库:USE 数据库名;。
    • 查看当前数据库:SELECT DB_NAME();。
    • 创建数据库:CREATE DATABASE(可指定文件路径、大小、增长量等参数)。

      数据类型
      • 数值型:bit(布尔)、tinyint(0-255,适合年龄)、int/bigint、decimal (p,s)(固定精度,适合分数)等。
      • 字符串型:char/nchar(定长,效率高但占内存)、varchar/nvarchar(变长,节省内存),n 前缀支持 Unicode,需根据场景选择(如手机号用 nchar (11),用户名用 nvarchar (50))。
      • 日期时间型:date(仅日期)、datetime/datetime2(日期 + 时间,精度不同)、smalldatetime(范围较小)等。
  • 表操作
    • 创建学生表:CREATE TABLE 表名(列名 列类型, ...)。
      1. CREATE TABLE 学生 (
      2. 学号 VARCHAR(8) NOT NULL,
      3. 姓名 VARCHAR(8) NOT NULL,
      4. 性别 VARCHAR(2) NOT NULL,
      5. 生日 DATE NOT NULL,
      6. 民族 VARCHAR(6) NOT NULL,
      7. 籍贯 VARCHAR(20) NOT NULL,
      8. 专业号 VARCHAR(4) NULL,
      9. 简历 VARCHAR(MAX) NULL,
      10. 登记照 VARCHAR(MAX) NULL,
      11. );
      复制代码

2.查询SQL

数据查询语言(DQL)核心语法

基础查询
查询所有列:SELECT * FROM 表名
查询指定列:SELECT 字段1, 字段2 FROM 表名
课后实例从game表中查询:

  1. --查询中文游戏名和英文游戏名,要求用 "@" 拼接起来, 并且用as关键字更改字段名
  2. SELECT 中文游戏名 + '@' + 英文游戏名 AS 中英文游戏名 FROM games;
复制代码

通过此段可以得出SELECT 之后写入你需要的数据表头名,后续进行表连接时更需要你锁定你需要的数据

条件查询
WHERE子句支持运算符:

  • 比较运算:=, <>(不等于)or!=, <, >, <=, >=
  • 范围匹配:BETWEEN...AND, IN(set), NOT IN
  • 空值判断:IS NULL, IS NOT NULL
  • 逻辑运算:AND, OR, NOT(优先级:NOT > AND > OR)
    1. --查询不是腾讯运营的角色扮演类网络游戏的中文名字
    2. SELECT 中文游戏名 FROM games WHERE 运营公司 NOT IN('腾讯') AND 游戏类别 ='角色扮演' AND 游戏模式='网络游戏';
    复制代码

在game1表中使用WHERE查找相应条件的数据

模糊查询
LIKE通配符:

  • _:匹配单个字符
  • %:匹配任意长度字符串(如'z%'匹配以z开头的值)
    1. --查询游戏英文名以L或者K或者J开头的游戏
    2. SELECT *FROM games WHERE 英文游戏名 LIKE 'L%' OR 英文游戏名 LIKE'K%' OR 英文游戏名 LIKE 'J%';
    复制代码

    LIKE一般在WHERE之后

字段控制

  • 去重:DISTINCT(如SELECT DISTINCT job FROM emp)
  • 字段运算:ISNULL(字段, 0)处理NULL值
  • 别名:字段 AS 别名(可省略AS)

排序
ORDER BY 字段1 [ASC|DESC], 字段2 [ASC|DESC]

  • 多字段排序时,前字段值相同则按后字段排序
    1. --查询魔幻题材类游戏评分在前10的游戏中文名,题材,评分
    2. SELECT TOP(10) 中文游戏名,游戏题材,评分 FROM games WHERE 游戏题材 = '魔幻' ORDER BY 评分 DESC;
    复制代码

聚合函数

  • COUNT(*):统计所有行
  • SUM()/AVG():计算和/平均值
  • MAX()/MIN():获取极值(支持字符串)

分组查询
GROUP BY 字段 HAVING 条件

  • 易混淆点:WHERE在分组前过滤,HAVING在分组后过滤(支持聚合函数)
    1. --找出中国各个项目得到金牌数量高于8枚的项目名和数量
    2. SELECT
    3. bigitem AS 项目名,
    4. COUNT(*) AS 金牌数量
    5. FROM king
    6. WHERE country = '中国'
    7. GROUP BY bigitem
    8. HAVING COUNT(*) > 8;
    复制代码

    先使用WHERE找到中国,再从其中项目进行分组,最后在这个组中找到金牌数量大于8的

分页查询(SQL Server)

  • 现代语法:OFFSET (页码-1)*行数 ROWS FETCH NEXT 行数 ROWS ONLY
  • 传统方案:嵌套TOP或ROW_NUMBER()

完整性约束类型

实体完整性

  • 主键约束:PRIMARY KEY(非空且唯一)
  • 唯一约束:UNIQUE(允许NULL,可多字段)
  • 自增长:IDENTITY(起始值, 增量)
    主键约束与唯一约束:主键只能有一个且不允许为空,唯一约束保证字段值唯一

域完整性

  • 非空约束:NOT NULL
  • 检查约束:CHECK(条件)(如age BETWEEN 15 AND 30)
  • 默认值:DEFAULT 值

引用完整性
外键约束语法:

  1. -- 建表时定义
  2. FOREIGN KEY (子表字段) REFERENCES 主表(主键)
  3. -- 已建表添加
  4. ALTER TABLE 子表 ADD CONSTRAINT 外键名
  5. FOREIGN KEY (字段) REFERENCES 主表(主键)
复制代码

约束作用

  • 阻止无效数据插入(如违反检查约束)
  • 防止误删被引用的主表记录

DQL执行顺序逻辑

  1. FROM:确定数据来源表
  2. WHERE:过滤原始数据行
  3. GROUP BY:按指定字段分组
  4. HAVING:筛选分组结果
  5. SELECT:选择输出字段
  6. ORDER BY:排序结果集
  7. 分页处理:截取最终数据片段

3.多表联查

联合查询

合并多个SELECT语句的结果集,要求列数和类型一致。

  • 并集查询:UNION(去重)或 UNION ALL(不去重),例如合并薪资低于2000和10号部门的员工记录。
  • 交集查询:INTERSECT返回多个结果集的共同记录,自动去重。
  • 差集查询:EXCEPT返回第一个结果集有但第二个没有的记录,自动去重。

    根据ven图理解
    UNION:我们所需要的结果就是红色和蓝色区域,中间绿色区域是双方共有的只会被保留一次
    UNION ALL :与UINON不同的是会把中间绿色共有的部分重复加入我们所需要的结果中
    INTERSECT:我们所得到的结果就是中间绿色区域内容,但是也只会保持一次
    EXCEPT:如果是红色EXCEPT蓝色,那么红色会把绿色内容去除掉然后保留剩余部分,反之蓝色EXCEPT红色,就与之相反
连接查询

通过主外键条件过滤笛卡尔积数据。

  • 内连接:仅返回满足条件的记录,语法为 INNER JOIN ... ON 或逗号分隔表名加WHERE条件(一般不写inner)。
    例如:
    1. -- 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称
    2. SELECT E1.Ename AS 员工姓名,E1.EmpNo AS 员工编号,d.Dname AS 部门名称 FROM Emp AS E1
    3. JOIN Dept d
    4. ON d.DeptNo =E1.DeptNo
    5. JOIN Emp AS E2
    6. ON E1.MGR=E2.EmpNo
    7. WHERE E1.HIREDATE < E2.HIREDATE;
    复制代码

    作业从emp表中查询,此时我们不写INNER也是可以的

  • 外连接
    • LEFT OUTER JOIN:左表记录全返回,右表不匹配则显示NULL一般在我们需要左表内容右表没有也需要的时候使用。
    • RIGHT OUTER JOIN:右表记录全返回,左表不匹配则显示NULL一般在我们需要右表内容左表没有也需要的时候使用。
    • FULL OUTER JOIN:返回左右表所有记录,无匹配侧显示NULL。
  • 自连接:同一表多次连接(需别名),例如查询员工及其领导姓名。
子查询

嵌套SELECT语句,按结果形态分类:

  • 标量子查询:返回单值,可直接用 =/>/< 等运算符。
    1. --列出在销售部工作的员工的姓名,假定不知道销售部的部门编号
    2. SELECT Ename AS 员工姓名
    3. FROM Emp
    4. WHERE DeptNo = (SELECT DeptNo FROM Dept WHERE Dname = '销售部');
    复制代码

    一般将其作为条件使用,如作业中查询姓名题,只要将销售部部门名作为条件加入到找寻其部门编号即可

  • 列子查询:返回一列多行,常用 IN/ANY/ALL 运算符。
  • 表子查询:返回多行多列,作为临时表参与查询
    例如:
    1. --列出所有职员的姓名及其部门名称,部门的人数
    2. SELECT Ename ,
    3. (SELECT D.Dname FROM Dept AS D WHERE D.DeptNo=E.DeptNo ) AS 部门名称,
    4. ( SELECT COUNT(*) FROM Emp AS E2 WHERE E2.DeptNo = E.DeptNo) AS 部门人数
    5. FROM Emp AS E
    复制代码

    此时

SQL Server系统函数

数值型函数
  • 绝对值:ABS
  • 取整:CEILING(上)、FLOOR(下)
  • 四舍五入:ROUND
  • 随机数:RAND
  • 三角函数(不常用):SIN/COS
字符串函数
  • 长度:LEN
  • 拼接:CONCAT
  • 截取:LEFT/RIGHT/SUBSTRING
    1. -- left(列名/值,长度) 从左侧字截取符串,返回字符串左边的若干个字符
    2. SELECT LEFT('hello world',2);
    3. -- right(列名/值,长度) 从右侧字截取符串,返回字符串左边的若干个字符
    4. SELECT RIGHT('hello world',2);
    5. -- substring(列名,开始位置,长度) 截取字符串,返回从指定位置开始的指定长度的字符换
    6. SELECT SUBSTRING('hello world',2,2);
    复制代码
  • 替换:REPLACE
  • 反转:REVERSE
日期和时间函数
  • 当前时间:GETDATE/SYSDATETIME
  • 提取日期部分:YEAR/MONTH/DAY
  • 日期增减:DATEADD
  • 差值计算:DATEDIFF
  • 格式化:FORMAT
流程控制函数
  • 条件判断:IIF
  • NULL处理:ISNULL
  • 多分支:CASE WHEN
    1. #iif函数:if else的效果 iif(条件,结果1,结果2)
    2. SELECT IIF(comm IS NULL,'没有奖金','有奖金') FROM emp;
    3. # ISNULL(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回原本的值
    4. #统计每个员工的月收入
    5. SELECT sal + ISNULL(comm,0) FROM emp;
    6. #case when 条件 then 结果 1 else 结果 2 end; 可以有多个 when
    7. #查询每个员工的姓名,薪水,以及工资情况
    8. # 情况: sal>=2500 高工资 2500>sal>=1500 中等工资 sal<1500 低工资
    9. SELECT ename,sal,CASE WHEN sal >=2500 THEN '高工资' WHEN sal >=1500 THEN '中等工资'
    10. ELSE '低工资' END 薪水情况 FROM emp;
    复制代码

注意事项

  1. 多表查询需明确关联条件,避免无效笛卡尔积。
  2. 联合查询需列数和类型严格匹配。
  3. 子查询需匹配运算符类型(单值、列或表)。
  4. 函数参数需符合类型要求(如日期格式)。
  5. 子查询和表连接有时候可以进行转换,这个时候我们一般使用子查询,因为子查询已经为查询过滤了一遍结果会使得效率更高更快

核心思想

通过关联条件整合多表数据,结合系统函数实现数据查询与加工
 

ADO编程

ADO.NET 是.NET Framework 中用于数据库访问的类库集,作为程序与数据源(SQL Server、MySQL、Oracle、XML 等)的桥梁,核心优势是断开式数据访问,可在断开数据库连接的情况下操作内存中的数据,减少服务器资源占用。
不同数据库依赖:SQL Server 无需额外 DLL,MySQL 需引入 mysql.data.dll 驱动。

数据库连接(SqlConnection/MySqlConnection)

ADO 数据库连接方法

string connect = "Serve = 服务器;Datebase = 数据库名;User Id = 用户名;Password=密码;"

string connect ="Serve = localhost;Datebase=数据库名;Integrated Security=Ture;"

数据库操作实现

using(SqlConnection 对象名1 =new SqlConnection(connect)){
对象名1.open()
string sql ="sql语句"
SqlCommmand 对象名2 = new SqlCommand(sql,对象名1);

带参数查询实现
string sql ="sql语句 @xxx"
对象名2.Parameters.Add(new SqlParameter("xxx",所需的值))

执行SQL命令方式

增删改操作
对象名2.ExecuteNonQuery()

单行查询
对象名2.ExecuteScalar()

结果集查询
SqlDateReader 对象名3 = 对象名2.ExcuteReader()
while(dataReader.Read())
{
Emp emp = new Emp();
emp.Empno = Convert.ToInt32(dataReader["empno"]);
emp.Ename = dataReader[1].ToString();
emp.Job = dataReader["job"].ToString();
emp.Mgr = Convert.ToInt32(dataReader["mgr"]);
emp.Hiredate = DateTime.Parse(dataReader["hiredate"].ToString());
emp.Sal = Convert.ToDecimal(dataReader["sal"]);
emp.Comm = dataReader.IsDBNull(6) ? 0m : Convert.ToDecimal(dataReader["comm"]);
emp.Deptno = Convert.ToInt32(dataReader["deptno"]);
emps.Add(emp);
}
例如:

  1. //登录操作
  2. static string Login(string user,string password)
  3. {
  4. string conection = "Server=localhost;Database=SuperMarket;Integrated Security=True";
  5. using (SqlConnection con = new SqlConnection(conection))
  6. {
  7. con.Open();
  8. string sql = @" SELECT COUNT(1)
  9. FROM[User]
  10. WHERE UserName = @user AND PassWord = @password";
  11. SqlCommand sqlCommand = new SqlCommand(sql, con);
  12. // sqlCommand.Parameters.Add(new SqlParameter("user",user));
  13. // sqlCommand.Parameters.Add(new SqlParameter("password", password));
  14. SqlParameter[] parameters = new SqlParameter[] {
  15. new SqlParameter("user", user),
  16. new SqlParameter("password", password)
  17. };
  18. sqlCommand.Parameters.AddRange(parameters);
  19. int row = Convert.ToInt32(sqlCommand.ExecuteScalar());
  20. Console.WriteLine(row);
  21. if (row > 0)
  22. {
  23. return "登陆成功";
  24. }
  25. else
  26. {
  27. return "登录失败";
  28. }
  29. }
  30. }
复制代码

作业中实现市场登录操作,此时返回单一结果使用ExecuteScalar(),返回查询到的结果数,大于0表示存在这个结果,所以可以表示登录成功

  1. //修改密码
  2. static void Update(string usename,string password )
  3. {
  4. string connect = "Server=localhost;Database=SuperMarket;Integrated Security=True";
  5. using (SqlConnection con = new SqlConnection(connect))
  6. {
  7. con.Open();
  8. string sql = @"UPDATE [User] set PassWord= @password WHERE UserName= @usename";
  9. SqlCommand sqlCommand = new SqlCommand(sql, con);
  10. sqlCommand.Parameters.Add(new SqlParameter("password", password));
  11. sqlCommand.Parameters.Add( new SqlParameter("usename", usename));
  12. int row = sqlCommand.ExecuteNonQuery();
  13. if(row > 0)
  14. {
  15. Console.WriteLine("修改成功");
  16. }
  17. else
  18. {
  19. Console.WriteLine("修改失败");
  20. }
  21. }
  22. }
复制代码

此时我们使用的是修改数据,使用使用了ExecuteNonQuery(),这个返回受影响的结果数,如果大于0表示我们成功影响了数据库里面的数据,可以用来告诉我们是否修改成功,同时这个函数也可以用于删除和增加中
|

数据解析方案

创建Emp类存储字段数据
使用List集合保存查询结果
通过遍历集合输出查询内容

断开式数据访问(DataSet + SqlDataAdapter)

DataSet
内存中的数据库,独立于数据源,包含多个 DataTable,支持复杂数据关系(主键、外键、约束)
可在内存中完成数据的增删改查(CURD),无需保持数据库连接

SqlDataAdapter
数据库与 DataSet 之间的桥梁,核心能力:
Fill():从数据库读取数据填充 DataSet/DataTable
Update():将 DataSet 中的修改同步回数据库(可配合 SqlCommandBuilder 自动生成更新命令,需表有主键)
支持自定义 Select/Insert/Update/Delete 命令
适用场景:离线处理数据、数据绑定、批量操作、复杂数据处理

事务(SqlTransaction)

事务特性(ACID)
原子性(全部执行或全部回滚)、一致性、隔离性、持久性

隔离级别(SQL Server)

隔离级别脏读不可重复读幻读并发性能
READ UNCOMMITTED可能可能可能最高
READ COMMITTED避免可能可能
REPEATABLE READ避免避免不可能
SERIALIZABLE避免避免避免

ADO.NET 事务使用
通过 SqlConnection.BeginTransaction() 创建事务
命令对象关联事务(Command.Transaction)
成功则 Commit(),异常则 Rollback()

封装(DBHelper)

将数据库连接、命令执行等通用操作封装为工具类,提升代码复用性、可读性,核心封装场景:
普通 SQL 的增删改(CUD 方法)
参数化 SQL 的增删改(防止 SQL 注入)
手写DBHelper函数:

  1. public class DBHeple
  2. {
  3. static string Connection = "Server=localhost;Database=SuperMarket;Integrated Security=True;";
  4. #region 增、删、改(普通的SQL语句)
  5. /// <summary>
  6. /// 增、删、改(普通的SQL语句)
  7. /// </summary>
  8. /// <param name="sql">普通的SQL语句</param>
  9. /// <returns>返回的受影响的行数/returns>
  10. public static int CUD(string sql)
  11. {
  12. SqlConnection con = null;
  13. try
  14. {
  15. con = new SqlConnection(Connection);
  16. con.Open();
  17. SqlCommand cmd = new SqlCommand(sql, con);
  18. int rs = cmd.ExecuteNonQuery();
  19. return rs;
  20. }
  21. catch(Exception ex)
  22. {
  23. Console.WriteLine("数据库连接错误");
  24. return -1;
  25. }
  26. finally
  27. {
  28. con.Close();
  29. }
  30. }
  31. #endregion
  32. #region 增、删、改(参数化SQL语句)
  33. /// <summary>
  34. /// 增、删、改(参数化SQL语句)
  35. /// </summary>
  36. /// <param name="sql">参数化SQL语句</param>
  37. /// <returns>返回的受影响的行数/returns>
  38. public static int CUD( string sql ,List<SqlParameter> sqlParameters)
  39. {
  40. SqlConnection con = null;
  41. try
  42. {
  43. con = new SqlConnection(Connection);
  44. con.Open();
  45. SqlCommand sqlCommand = new SqlCommand(sql, con);
  46. sqlCommand.Parameters.AddRange(sqlParameters.ToArray());
  47. int rs = sqlCommand.ExecuteNonQuery();
  48. return rs;
  49. }
  50. catch(Exception ex)
  51. {
  52. Console.WriteLine("数据库连接错误");
  53. return -1;
  54. }
  55. finally
  56. {
  57. con?.Close();
  58. }
  59. }
  60. #endregion
  61. #region 执行查询操作,返回SqlDataReader对象
  62. /// <summary>
  63. /// 执行查询操作,返回SqlDataReader对象
  64. /// </summary>
  65. /// <param name="sql">普通的SQL语句</param>
  66. /// <returns>返回的SqlDataReader对象</returns>
  67. public static SqlDataReader GetReader(string sql)
  68. {
  69. SqlConnection conn = new SqlConnection(Connection);
  70. conn.Open();
  71. SqlCommand sqlCommand = new SqlCommand(sql, conn);
  72. try
  73. {
  74. return sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
  75. }
  76. catch (Exception)
  77. {
  78. throw;
  79. }
  80. }
  81. #endregion
  82. #region 执行查询操作,返回SqlDataReader对象(参数化SQL语句)
  83. /// <summary>
  84. /// 执行查询操作,返回SqlDataReader对象(参数化SQL语句)
  85. /// </summary>
  86. /// <param name="sql">参数化SQL语句</param>
  87. /// <returns>返回的SqlDataReader对象</returns>
  88. public static SqlDataReader GetReader(string sql , List<SqlParameter> sqlParameters)
  89. {
  90. SqlConnection conn = new SqlConnection(Connection);
  91. conn.Open();
  92. SqlCommand command = new SqlCommand(sql, conn);
  93. command.Parameters.AddRange(sqlParameters.ToArray());
  94. try
  95. {
  96. return command.ExecuteReader(CommandBehavior.CloseConnection);
  97. }
  98. catch (Exception e)
  99. { return null; }
  100. }
  101. #endregion
  102. #region 执行查询操作,返回DataTable对象(普通SQL语句)
  103. /// <summary>
  104. /// 执行查询操作,返回DataTable对象(普通SQL语句)
  105. /// </summary>
  106. /// <param name="sql">普通sql语句</param>
  107. /// <returns>返回DataTable</returns>
  108. public static DataTable GetDataTable(string sql)
  109. {
  110. SqlConnection con =null;
  111. try
  112. {
  113. con = new SqlConnection(Connection);
  114. con.Open();
  115. SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sql, con);
  116. DataTable table = new DataTable();
  117. sqlDataAdapter.Fill(table);
  118. return table;
  119. }catch(Exception e)
  120. {
  121. return null ;
  122. }
  123. finally
  124. {
  125. con.Close();
  126. }
  127. }
  128. #endregion
  129. #region 执行查询操作,返回DataTable对象(参数化SQL语句)
  130. /// <summary>
  131. /// 执行查询操作,返回DataTable对象(参数化SQL语句)
  132. /// </summary>
  133. /// <param name="sql">带@参数化SQL语句</param>
  134. /// <returns>返回DataTable</returns>
  135. public static DataTable GetDataTable(string sql ,List<SqlParameter> sqlParameters)
  136. {
  137. SqlConnection con = null;
  138. try
  139. {
  140. con = new SqlConnection(Connection);
  141. con.Open();
  142. SqlCommand comd = new SqlCommand (sql, con);
  143. comd.Parameters.AddRange(sqlParameters.ToArray());
  144. SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
  145. sqlDataAdapter.SelectCommand = comd;
  146. DataTable table = new DataTable();
  147. sqlDataAdapter.Fill(table);
  148. return table;
  149. }
  150. catch (Exception e)
  151. {
  152. return null;
  153. }
  154. finally { con.Close(); }
  155. }
  156. #endregion
  157. #region 执行查询语句,返回第一行第一个单元格中的数据(普通SQL语句)
  158. /// <summary>
  159. /// 执行查询语句,返回第一行第一个单元格中的数据
  160. /// </summary>
  161. /// <param name="sql">普通的SQL语句</param>
  162. /// <returns>返回第一行第一个单元格中的数据</returns>
  163. public static object GetScalar(string sql)
  164. {
  165. SqlConnection con = null;
  166. try
  167. {
  168. con = new SqlConnection(Connection);
  169. con.Open();
  170. SqlCommand sqlCommand = new SqlCommand (sql, con);
  171. object rs = sqlCommand.ExecuteScalar();
  172. return rs;
  173. }catch (Exception e)
  174. {
  175. return null;
  176. }
  177. finally
  178. {
  179. con.Close();
  180. }
  181. }
  182. #endregion
  183. #region 执行查询语句,返回第一行第一个单元格中的数据(参数化SQL语句)
  184. /// <summary>
  185. /// 执行查询语句,返回第一行第一个单元格中的数据(参数化SQL语句)
  186. /// </summary>
  187. /// <param name="sql">参数化SQL语句</param>
  188. /// <returns>返回第一行第一个单元格中的数据</returns>
  189. public static object GetScalar (string sql,List<SqlParameter> sqlParameters)
  190. {
  191. SqlConnection con = null;
  192. try
  193. {
  194. con = new SqlConnection(Connection);
  195. con.Open();
  196. SqlCommand sqlCommand = new SqlCommand(sql, con);
  197. sqlCommand.Parameters.AddRange(sqlParameters.ToArray());
  198. object rs = sqlCommand.ExecuteScalar();
  199. return rs;
  200. }
  201. catch (Exception e)
  202. {
  203. return null;
  204. }
  205. finally
  206. {
  207. con.Close ();
  208. }
  209. }
  210. #endregion
  211. }
复制代码

执行查询操作,返回SqlDataReader对象时,要注意不能简单的在后面写finally{con.Close()}因为运行SqlDataReader时要保持连接畅通

核心思想

连接式访问:SqlConnection + SqlCommand(需保持连接,适合简单、即时操作)
断开式访问:SqlDataAdapter + DataSet(离线操作,适合复杂数据处理、批量更新)
事务:保证多操作的原子性,避免数据不一致
封装:简化重复操作,统一异常处理

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行