一、常用数据类型:
- image类型,用来存储byte[]
- char
- nchar
- varchar
- nvarchar
- text
- ntext
- varchar(max)
- nvarchar(max)
以上这些数据类型都表示字符串。
字符串数据类型:
| char(n) | [定长](空格补充) 非unicode |
|---|---|
| nchar(n) | [定长] unicode数据 |
| varchar(n) | [变长] 非unicode |
| nvarchar(n) | [变长] unicode数据 |
1. 带n和不带n的区别:
不带n的数据类型(非unicode),存储中文等双字节字符,占用两个字节,存储英文,数字等每个字符占用1个字节。
例如: char(2) 表示可以存储2个字节。例如:ab,12, 赵
带n的(unicode),无论存储中文还是英文、数字等,每个字符都是占用两个字节。
例如:nchar(2)表示可以存储两个字符,每个字符占用2个字节。
不带n的这些数据类型,长度最长可以设置为8000,而带n的这些数据类型,长度最长可以设置为4000.
2. 带var和不带var的区别:
比如:
varchar
nvarchar
char
nchar
带var的表示的是:可变长度。
不带var的表示的是:固定长度。
固定长度,如下,存储1个字节也是要占用10个字节的,会自动补9个空格。
&emspchar(10) 1
1111111111
可变长度,会根据实际数据的大小动态重新分配存储空间,相对来说节省村存储空间。
varchar(10)
10表示最多10个字节,如果存储的数据超过10个字节,那么无论是固定长度还是可变长度都会报错。
下面的格式是用来存储大的数据:
varchar(max)
nvarchar(max)
3.数据库的完整性:
2.2数据库的完整性:
主键:主键是用来唯一标识表中某一行的属性或者属性组,一个表只能有一个主键。因为主键可以唯一的标识某一行记录,可以确保进行数据更新,删除的时候不会出现张冠李戴。
- 没个表都应该有唯一一个主键;
- 主键不包含null值(不允许为空);
外键:由一个列或多个列组合构成,用来实线两张表之间的数据联系,维护两个表之间的一至性关系。限制可以保存在外键所在表中的数据。*
- 修改父表主键时检查;
- 删除父表记录时检查;
- 在子表中插入数据时检查;
二、数据库操作
使用代码创建数据库和数据表
创建数据库:
create database student;
创建数据表:(以SQL Server 2014数据库为例)
CREATE DATABASE CNTF
GO
USE CNTF
CREATE table group_info
(
groupid int primary key identity(1,1),
groupname varchar(50) not null,
)
create table useinfo
(
userid int primary key identity(1,1),
groupid int foreign key references group_info(groupid),
username varchar(50) not null,
age int not null,
sex varchar(2) not null,
address varchar(50),
)
1.insert语句操作(增)
向表中插入数据:
基本的语法如下所示:
insert into 表名(列1,列2,列3) values(值1,值2,值3)
例如:
insert into student(name) value("王xx")
1) 代码格式化——折行
以关键字作为转折:
insert INTO
student_1(name,sex,age,majore)
VALUES('江水','男',16,'控制工程')
如果向表中的所有列(除自动编号以外的所有列)都要插入值,那么可以省略列名,同时必须保证后面的值列表中的顺序必须与表中列的顺序一致。
insert INTO
student_1
VALUES('王','男',16,'工程')
可以向表中插入部分列,另外一部分列不插入:
没有插入数据的列为null
insert INTO
student_1(name)
VALUES('江水')
2)向自动编号列插入数值:
首先启动某个表的“自动编号列”手动插入值的功能:
SET IDENTITY_INSERT class ON
INSERT INTO
class(id,name)
values(20,'WANG')
SET IDENTITY_INSERT class OFF
2.数据更新:updata
更新数据基本语句:
updata 表名 set 列=新值1,列2=新值2,...where 条件
1. 应用实例如下:
UPDATE student_1 set name='王云飞' where age=32
&emps;&emps; 在sql语句中,判断使用单等号“=”。
数据更新实例:

3.数据删除:
1)删除数据 基本语法:
delete语句如果不加where条件,表示将表中所有的数据都删除,加where条件后,会按照where条件进行删除。
delet from 表名 where ...
例如:有条件删除
DELETE from student_1 where name='王xx'
2) 删除表中的所有数据:
- delete from 表名
- truncate table 表名
如果确实要删除表中的全部数据,建议使用truncate, truncate特点如下:
- truncate语句不能跟where条件(无法根据条件来删除,只能全部删除数据)
- 同时自动编号恢复到初始值
- 使用truncate删除表中的数据要比delete效率搞得多。
- truncate删除数据,不触发触发器。
3. 数据查询:
基本语句如下所示:
select * from 表名 //查询表中的所有数据
查询特别的列以及特别的行(where条件筛选部分行显示):
SELECT name from student_1 where id=1
1)为查询结果集中的列起别名:
SELECT id as 学生编号,name as 学生姓名 from student_1 where id=1
代码格式化:
SELECT
id as 学生编号,
name as 学生姓名
from student_1 where id=1
select 并不是必须与from配合使用,select也可以单独使用。
2)去掉重复数据 (distinct)
distinct关键字,针对已经查询出的结果,去掉重复数据。
select distinct name from student_1name
3)Top 关键字获取前几条数据:
top一般都与order by 连用。
排序:
按照年龄降序排序:
select * from class order by age desc
按照年龄升序排序(默认即为升序排序)
select * from class order by age desc
结合top 以及order by排序拿到前5个数据:
mysql不支持这种查询方式:
select top 5 * from student.student_1 order by id DESC
在mysql中使用limit 关键字
select * from student.student_1 order by id DESC limit 2
4)条件查询:
//查询连续的数据建议使用下面的方式
select * from student.student_1 where id BETWEEN 1 and 5
//查询随机的数据建议使用下面的方式
select * from student.student_1 where id in(1,3,7)
三、ADO.NET数据库操作(通过代码操作数据库)
ADO.NET组成:
-
数据提供程序(常用类)
1. Connection: 用来连接数据库
2. Command: 用来执行sql语句
3. DataReader: 只读、只进的结果集,一条一条读取数据(StreamReader、XmlReader微软的类库中Reader的使用方式都差不多)
4. DataAdapter, 一个封装了上面三个对象的对象。 -
数据集(DataSet), 临时数据库;
断开式数据操作。
1)连接字符串的节本流程:
//连接数据库的基本步骤:
//1. 创建连接字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象,并且将连接字符串传进来。
using (MySqlConnection con=new MySqlConnection (constr)) //using 相当于是try...finally。 在finally中调用对象的dispose()方法。
{
//测试,打开连接
//3.打开连接(如果打开数据连接没有问题,表示连接成功!)
con.Open();
//4.关闭连接,释放资源
//con.Close(); //该函数在con.Dispose()中默认已经调用,所以也不用写
//con.Dispose(); //using会自动调用该函数,因此不用写。
}
2) ADO.NET 向数据库插入一条数据
以下三个语句都可以执行基本的数据库增、删、查、改的目的。但是每个方法针对不同的操作拿到正确的数据。
ExecuteNonQuery()方法的返回值为一个int类型,表示执行Insert\delete\updata语句后所影响的行数。若是执行其他的语句(例如查询语句)返回值为-1.
int r= cmd.ExecuteNonQuery(); //Insert\delete\updata操作通常用该方法
cmd.ExecuteScalar(); //当执行返回单个结果的时候,调用该方法
cmd.ExecuteReader(); //当查询出多行,多列结果的时候。
private void button1_Click(object sender, EventArgs e)
{
//向表中插入一条数据:
//1. 创建连接字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象,并且将连接字符串传进来。
using (MySqlConnection con=new MySqlConnection (constr)) //using 相当于是try...finally。 在finally中调用对象的dispose()方法。
{
//3. 编写sql语句
string sql = "insert into student.student_1 (name,sex,age,majore) VALUES('郭大路','男',32,'师法')";
//4. 创建一个执行sql语句的对象(命令对象),SqlCommand
using(MySqlCommand cmd=new MySqlCommand (sql,con))
{
//最晚打开,最早关闭,节省资源。
//5.打开连接(连接对象最晚打开,最早关闭,节省资源。)
con.Open();
//6.开始执行SQL语句
//一下三个语句都可以执行基本的数据库增、删、查、改的目的。但是每个方法针对不同的操作会有更好的效果。
//ExecuteNonQuery()方法的返回值为一个int类型,表示执行Insert\delete\updata语句后所影响的行数。若是执行其他的语句(例如查询语句)返回值为-1.
int r= cmd.ExecuteNonQuery(); //Insert\delete\updata操作通常用该方法
//cmd.ExecuteScalar(); //当执行返回单个结果的时候,调用该方法
//cmd.ExecuteReader(); //当查询出多行,多列结果的时候。
textBox1.Text = (r.ToString());
}
//4.关闭连接,释放资源
//con.Close(); //该函数在con.Dispose()中默认已经调用,所以也不用写
//con.Dispose(); //using会自动调用该函数,因此不用写。
}
}
3) ADO.NET 删除数据库中的一条数据
private void button1_Click(object sender, EventArgs e)
{
//删除表中的一条数据:
//1. 创建连接字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象,并且将连接字符串传进来。
using (MySqlConnection con=new MySqlConnection (constr))
{
//3.创建所要执行的SQL语句
string sql = "delete from student.student_1 where id=3";
//4.创建Command对象,用来执行SQL语句
using (MySqlCommand cmd=new MySqlCommand (sql,con))
{
//5.打开连接,连接数据库
con.Open();
//6.执行sql语句,进行数据库操作
cmd.ExecuteNonQuery();
}
//7.关闭连接,释放资源
}
}
4)ADO.NET 更新数据库中的一条数据:
private void button1_Click(object sender, EventArgs e)
{
//更改数据库中的一条数据
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象,并且将连接字符串传进来。
using (MySqlConnection con=new MySqlConnection (constr))
{
//3.创建所要执行的SQL语句
string sql = "UPDATE student.student_1 set name='燕七' where id=8";
//4.创建Command对象,用来执行SQL语句
using (MySqlCommand cmd=new MySqlCommand (sql,con))
{
//5.打开连接,连接数据库
con.Open();
//6.执行sql语句,进行数据库操作
cmd.ExecuteNonQuery();
}
//7.关闭连接,释放资源
}
}
5) ADO.Net 查询出数据库中数据表的数据条数:
cmd.ExecuteScalar(); //当执行返回单个结果的时候,调用该方法
private void button1_Click(object sender, EventArgs e)
{
//查询数据表中的数据个数
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象,并且将连接字符串传进来。
using (MySqlConnection con=new MySqlConnection (constr))
{
//3.创建所要执行的SQL语句
string sql = "select COUNT(*) from student.student_1";
//4.创建Command对象,用来执行SQL语句
using (MySqlCommand cmd=new MySqlCommand (sql,con))
{
//5.打开连接,连接数据库
con.Open();
//6.执行sql语句,进行数据库操作
//ExecuteScalar()返回值为object
//注意:单sql语句执行的时候,如果是聚合函数,
//那么ExecuteScalar()返回不可能是null,因为聚合函数不会返回null,
//但是如果sql语句使用的不是聚合函数,那么ExecuteScalar()方法游客可能返回null.
//那么在使用count变量的时候就需要先判断是否为Null.
object count=cmd.ExecuteScalar();
textBox1.Text = count.ToString();
}
//7.关闭连接,释放资源
}
}
4. 使用SqlDataReader获取数据表中的多行多列数据:
MySqlDataReader reader = cmd.ExecuteReader()获取数据的原理如下图所示:

1)DataReader 的特点
- 只读,只进(不能后退)。只能通过reader读取数据,不能修改数据。reader只能一条一条向前移动,不能后退也不能跳跃;
- 使用reader的时候必须保证连接是打开状态。
- 当reader使用完毕之后,必须把reader关闭,释放。同时关闭释放连接对象。
- 默认情况下,DataReader要求独占一个连接对象。
private void button1_Click(object sender, EventArgs e)
{
//查询数据表中的多行多列数据
//1.创建连接字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.创建连接对象
using (MySqlConnection con=new MySqlConnection (constr))
{
//3. 创建sql语句
string sql = "select * from student.student_1";
//4.创建Command对象用来执行sql语句
using(MySqlCommand cmd=new MySqlCommand (sql,con))
{
//5.打开连接
con.Open();
//6.执行sql语句
//由于SqlDataReader对象在使用完之后也要调用Close()方法和Dispose()方法,因此使用using();
//通过调用ExecuteReader()方法,将给定的SQL语句在服务器端执行。
//执行完毕之后,服务器端已经查询出了数据,但是数据是保存在数据库服务器的内存当中,并没有返回给应用程序。
//只是返回给应用程序一个Reader对象,这个对象就是用来获取数据的对象。
using (MySqlDataReader reader = cmd.ExecuteReader())
{
//接下来要通过reader对象一条一条获取数据
//1. 在获取数据之前,先判断一下本次执行查询后是否查询到了数据。
if (reader.HasRows)
{
//2.如果有数据,那么接下来就要一条一条获取数据
//每次获取数据之前,都要调用reader.Read()方法,向后移动一条数据,如果成功移动到了某条数据上,则返回true,否则返回false;
while(reader.Read())
{
//获取当前reader指向的数据
//reader.FiledCount,可以获取当前查询语句查询出的列的个数。
for(int i=0;i<reader.FieldCount;i++)
{
//GetValue()只能通过索引获取数据值
// textBox1.Text = textBox1.Text + reader.GetValue(i) + " | ";
//索引器reader[],可以使用列名来获取列的值。
textBox1.Text = textBox1.Text + reader[i] + " | ";
}
}
}
else
{
MessageBox.Show("没有任何数据");
}
}
}
//7.关闭连接
}
}
四、登录以及带参数的sql语句
应用sql语句制作的登录程序:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace 登录
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//获得前台客户端输入的 用户名
string user_id=useId.Text.Trim();
//获得前台客户端输入的密码
string user_password = passWord.Text.Trim();
//数据库操作
//1. 连接数据库字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
//2.连接对象
using (MySqlConnection con =new MySqlConnection (constr))
{
//3.准备sql语句
//首先取到与用户名相同的那一行的所有数据,然后在判断密码是否正确
string sql = string.Format("select * from user where user_id='{0}'", user_id);
//4.准备Command对象,用来执行sql语句
using (MySqlCommand cmd=new MySqlCommand (sql,con))
{
//打开数据库连接
con.Open();
//使用DataReader 逐条读取数据
using (MySqlDataReader reader=cmd.ExecuteReader())
{
//判断reader是否读取到了数据,若是没有数据,那么不存在该用户名,提醒用户注册。
if(reader.HasRows)
{
//存在该用户
//使用reader.Read()函数读取下一条数据(也就是密码)。判断密码是否正确
if(reader.Read())
{
//比较密码是否正确
//reader.GetString(2)获取指定列的字符串形式的值
string pwd = reader.GetString(2);
if(pwd==user_password)
{
MessageBox.Show("登录成功");
}
else
{
MessageBox.Show("登录失败");
}
}
}
else if(user_id.Length!=0)
{
MessageBox.Show("用户名不存在");
}
}
}
}
}
}
}
1. 带参数的sql语句
为了防止sql语句注入攻击,使用带参数的sql语句或者是存储过程。
#region 带参数的sql语句
//数据库操作
//1. 连接数据库字符串
string constr = "Server=localhost;Data Source=127.0.0.1;User ID=root;Password=root;DataBase=bridgemap;Charset=utf8;";
using (MySqlConnection con = new MySqlConnection(constr))
{
//sql语句
// string sql = string.Format("select * from user where user_id='{0}'", user_id);
//变量名可以自己起。
string sql = "select * from user where user_id=@user_id";
using (MySqlCommand cmd = new MySqlCommand(sql, con))
{
//当使用带参数的sql语句的时候,
//1> sql语句中会出现参数
//2> 如果sql语句中有参数,那么必须在command对象中提供对应的参数和值。
//创建参数对象,并使用对象初始化器对他赋值
//MySqlParameter paramUser_Id = new MySqlParameter("@user_id",MySqlDbType.VarChar,255) { Value=useId.Text.Trim()};
//将参数加到command对象中
//cmd.Parameters.Add(paramUser_Id);
//--------------------------------------------------------------------------------------------
//使用参数数组的形式,可以一次性定义多个参数
MySqlParameter[] pms = new MySqlParameter[]{
new MySqlParameter("@user_id",MySqlDbType.VarChar,255) { Value=useId.Text.Trim()},
};
//向command 对象中增加参数
cmd.Parameters.AddRange(pms);
//---------------------------------------------------------------------------------------------
//打开数据库连接
con.Open();
//使用DataReader 逐条读取数据
using (MySqlDataReader reader = cmd.ExecuteReader())
{
//判断reader是否读取到了数据,若是没有数据,那么不存在该用户名,提醒用户注册。
if (reader.HasRows)
{
//存在该用户
//使用reader.Read()函数读取下一条数据(也就是密码)。判断密码是否正确
if (reader.Read())
{
//比较密码是否正确
//reader.GetString(2)获取指定列的字符串形式的值
string pwd = reader.GetString(2);
if (pwd == passWord.Text.Trim())
{
MessageBox.Show("登录成功");
}
else
{
MessageBox.Show("登录失败");
}
}
}
else if (useId.Text.Trim().Length != 0)
{
MessageBox.Show("用户名不存在");
}
}
}
}
#endregion
本文详细介绍了数据库操作的基础知识,包括数据类型的使用,如image、char、nchar、varchar、nvarchar等,以及如何创建数据库和数据表。此外,还深入探讨了SQL语句的应用,如insert、update、delete和select,以及如何通过ADO.NET进行数据库操作,包括插入、删除、更新和查询数据。同时,文章还提供了使用带参数的SQL语句和存储过程的方法,以防止SQL注入攻击。

503

被折叠的 条评论
为什么被折叠?



