Delphi+SQL Server实现的(GUI)户籍管理系统
1.项目简介
本项目是一个户籍管理系统,用于记录住户身份信息,提供新户登记(增加)、户籍变更(修改)、户籍注销(删除)、户籍查询、曾用名查询、迁户记录查询以及创建备份、删除备份共8个功能。
1.1. 软件环境与开发工具
- 操作系统:Windows 10 Home China 1809 17763
- 数据库:SQL Server Express 2017
- 集成开发环境:Embarcadero Delphi Architect 10.3
2. 数据库设计
2.1. 概要结构设计
数据库Manager
共包括以下3张表:
表名 | 说明 |
| 存储用户信息,是程序的核心表 |
| 存储用户改名记录,作为曾用名表 |
| 存储用户的住址变更记录,作为户籍变更历史 |
| 存储系统管理员账户信息 |
2.2. 数据表结构分析
4张数据表的字段分别列举如下:
字段名 | 含义 | 类型 |
| 姓名 |
|
| 性别 |
|
| 身份证号(主键) |
|
| 户籍地址 |
|
| 联系方式 |
|
| 更新时间 |
|
字段名 | 含义 | 类型 |
| 身份证号(主键) |
|
| 曾用名 |
|
| 改名时间(升序索引) |
|
字段名 | 含义 | 类型 |
| 身份证号(主键) |
|
| 曾用户籍地 |
|
| 迁户时间(升序索引) |
|
字段名 | 含义 | 类型 |
| 用户名(主键) |
|
| 别名 |
|
| 密码 |
|
2.3建表语句
USE [Manager]
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Rename', @level2type=N'CONSTRAINT',@level2name=N'FK_Rename_People'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_Tel_Limit'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_Sex_Limit'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_ID_Limit'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Date'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Tel_No'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Address'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'ID_Num'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Sex'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Move', @level2type=N'CONSTRAINT',@level2name=N'FK_Move_People'
GO
ALTER TABLE [dbo].[People] DROP CONSTRAINT [CK_Tel_Limit]
GO
ALTER TABLE [dbo].[People] DROP CONSTRAINT [CK_Sex_Limit]
GO
ALTER TABLE [dbo].[People] DROP CONSTRAINT [CK_ID_Limit]
GO
ALTER TABLE [dbo].[Rename] DROP CONSTRAINT [FK_Rename_People]
GO
ALTER TABLE [dbo].[People] DROP CONSTRAINT [FK_People_People]
GO
ALTER TABLE [dbo].[Move] DROP CONSTRAINT [FK_Move_People]
GO
/****** Object: Index [IX_Rename_1] Script Date: 2019/5/27 1:20:03 ******/
DROP INDEX [IX_Rename_1] ON [dbo].[Rename]
GO
/****** Object: Index [IX_Rename] Script Date: 2019/5/27 1:20:03 ******/
DROP INDEX [IX_Rename] ON [dbo].[Rename]
GO
/****** Object: Index [IX_Move_1] Script Date: 2019/5/27 1:20:03 ******/
DROP INDEX [IX_Move_1] ON [dbo].[Move]
GO
/****** Object: Index [IX_Move] Script Date: 2019/5/27 1:20:03 ******/
DROP INDEX [IX_Move] ON [dbo].[Move]
GO
/****** Object: Table [dbo].[Rename] Script Date: 2019/5/27 1:20:03 ******/
DROP TABLE [dbo].[Rename]
GO
/****** Object: Table [dbo].[People] Script Date: 2019/5/27 1:20:03 ******/
DROP TABLE [dbo].[People]
GO
/****** Object: Table [dbo].[Move] Script Date: 2019/5/27 1:20:03 ******/
DROP TABLE [dbo].[Move]
GO
USE [master]
GO
/****** Object: Database [Manager] Script Date: 2019/5/27 1:20:03 ******/
DROP DATABASE [Manager]
GO
/****** Object: Database [Manager] Script Date: 2019/5/27 1:20:03 ******/
CREATE DATABASE [Manager] ON PRIMARY
( NAME = N'Citizens', FILENAME = N'D:\Program_Files_(x64)\Microsoft\SQL_Server_2017\Instances\MSSQL14.EXPRESS17\MSSQL\UserData\Citizens.mdf' , SIZE = 8192KB , MAXSIZE = 1048576KB , FILEGROWTH = 1%)
LOG ON
( NAME = N'Citizens_log', FILENAME = N'D:\Program_Files_(x64)\Microsoft\SQL_Server_2017\Instances\MSSQL14.EXPRESS17\MSSQL\UserData\Citizens_log.ldf' , SIZE = 8192KB , MAXSIZE = 1048576KB , FILEGROWTH = 1%)
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [Manager].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [Manager] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [Manager] SET ANSI_NULLS OFF
GO
ALTER DATABASE [Manager] SET ANSI_PADDING OFF
GO
ALTER DATABASE [Manager] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [Manager] SET ARITHABORT OFF
GO
ALTER DATABASE [Manager] SET AUTO_CLOSE ON
GO
ALTER DATABASE [Manager] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [Manager] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [Manager] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [Manager] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [Manager] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [Manager] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [Manager] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [Manager] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [Manager] SET DISABLE_BROKER
GO
ALTER DATABASE [Manager] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [Manager] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [Manager] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [Manager] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [Manager] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [Manager] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [Manager] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [Manager] SET RECOVERY SIMPLE
GO
ALTER DATABASE [Manager] SET MULTI_USER
GO
ALTER DATABASE [Manager] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [Manager] SET DB_CHAINING OFF
GO
USE [Manager]
GO
/****** Object: Table [dbo].[Move] Script Date: 2019/5/27 1:20:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Move](
[ID_Num] [char](18) NOT NULL,
[Address] [nvarchar](100) NOT NULL,
[Date] [datetime] NOT NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[People] Script Date: 2019/5/27 1:20:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[People](
[Name] [nvarchar](10) NOT NULL,
[Sex] [nchar](2) NOT NULL,
[ID_Num] [char](18) NOT NULL,
[Address] [nvarchar](100) NOT NULL,
[Tel_No] [numeric](12, 0) NOT NULL,
[Date] [datetime] NOT NULL,
CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED
(
[ID_Num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Rename] Script Date: 2019/5/27 1:20:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Rename](
[ID_Num] [char](18) NOT NULL,
[Old_Name] [char](10) NOT NULL,
[Date] [datetime] NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Move] ([ID_Num], [Address], [Date]) VALUES (N'440101200101010101', N'北京市', CAST(N'2019-05-27T00:14:47.990' AS DateTime))
INSERT [dbo].[Move] ([ID_Num], [Address], [Date]) VALUES (N'440111201111111111', N'上海', CAST(N'2019-05-27T00:34:22.500' AS DateTime))
INSERT [dbo].[Move] ([ID_Num], [Address], [Date]) VALUES (N'440111201111111111', N'杭州', CAST(N'2019-05-27T00:35:12.933' AS DateTime))
INSERT [dbo].[Move] ([ID_Num], [Address], [Date]) VALUES (N'440111201111111111', N'杭州', CAST(N'2019-05-27T00:35:44.370' AS DateTime))
INSERT [dbo].[People] ([Name], [Sex], [ID_Num], [Address], [Tel_No], [Date]) VALUES (N'John', N'男 ', N'440101200101010101', N'北京市', CAST(13333333333 AS Numeric(12, 0)), CAST(N'2019-05-27T00:23:28.633' AS DateTime))
INSERT [dbo].[People] ([Name], [Sex], [ID_Num], [Address], [Tel_No], [Date]) VALUES (N'Ben', N'男 ', N'440111201111111111', N'杭州', CAST(13333333333 AS Numeric(12, 0)), CAST(N'2019-05-27T00:35:44.367' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Alice ', CAST(N'2019-05-27T00:08:35.767' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Alice ', CAST(N'2019-05-27T00:14:47.987' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Cindarela ', CAST(N'2019-05-27T00:15:07.933' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Alice ', CAST(N'2019-05-27T00:18:24.390' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Bob ', CAST(N'2019-05-27T00:19:22.057' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'Ben ', CAST(N'2019-05-27T00:20:54.577' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440101200101010101', N'John ', CAST(N'2019-05-27T00:23:28.633' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440111201111111111', N'Alice ', CAST(N'2019-05-27T00:34:22.500' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440111201111111111', N'Ben ', CAST(N'2019-05-27T00:35:12.930' AS DateTime))
INSERT [dbo].[Rename] ([ID_Num], [Old_Name], [Date]) VALUES (N'440111201111111111', N'Ben ', CAST(N'2019-05-27T00:35:44.370' AS DateTime))
SET ANSI_PADDING ON
GO
/****** Object: Index [IX_Move] Script Date: 2019/5/27 1:20:03 ******/
CREATE NONCLUSTERED INDEX [IX_Move] ON [dbo].[Move]
(
[ID_Num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_Move_1] Script Date: 2019/5/27 1:20:03 ******/
CREATE UNIQUE NONCLUSTERED INDEX [IX_Move_1] ON [dbo].[Move]
(
[Date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object: Index [IX_Rename] Script Date: 2019/5/27 1:20:03 ******/
CREATE NONCLUSTERED INDEX [IX_Rename] ON [dbo].[Rename]
(
[ID_Num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_Rename_1] Script Date: 2019/5/27 1:20:03 ******/
CREATE UNIQUE NONCLUSTERED INDEX [IX_Rename_1] ON [dbo].[Rename]
(
[Date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = ON, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Move] WITH CHECK ADD CONSTRAINT [FK_Move_People] FOREIGN KEY([ID_Num])
REFERENCES [dbo].[People] ([ID_Num])
GO
ALTER TABLE [dbo].[Move] CHECK CONSTRAINT [FK_Move_People]
GO
ALTER TABLE [dbo].[People] WITH CHECK ADD CONSTRAINT [FK_People_People] FOREIGN KEY([ID_Num])
REFERENCES [dbo].[People] ([ID_Num])
GO
ALTER TABLE [dbo].[People] CHECK CONSTRAINT [FK_People_People]
GO
ALTER TABLE [dbo].[Rename] WITH CHECK ADD CONSTRAINT [FK_Rename_People] FOREIGN KEY([ID_Num])
REFERENCES [dbo].[People] ([ID_Num])
GO
ALTER TABLE [dbo].[Rename] CHECK CONSTRAINT [FK_Rename_People]
GO
ALTER TABLE [dbo].[People] WITH CHECK ADD CONSTRAINT [CK_ID_Limit] CHECK ((len([ID_Num])=(15) OR len([ID_Num])=(18)))
GO
ALTER TABLE [dbo].[People] CHECK CONSTRAINT [CK_ID_Limit]
GO
ALTER TABLE [dbo].[People] WITH CHECK ADD CONSTRAINT [CK_Sex_Limit] CHECK (([Sex]='男' OR [Sex]='女'))
GO
ALTER TABLE [dbo].[People] CHECK CONSTRAINT [CK_Sex_Limit]
GO
ALTER TABLE [dbo].[People] WITH CHECK ADD CONSTRAINT [CK_Tel_Limit] CHECK ((len([Tel_No])>=(10) AND len([Tel_No])<=(12)))
GO
ALTER TABLE [dbo].[People] CHECK CONSTRAINT [CK_Tel_Limit]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'身份证绑定' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Move', @level2type=N'CONSTRAINT',@level2name=N'FK_Move_People'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'性别' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Sex'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'身份证号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'ID_Num'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'家庭住址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Address'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'联系方式' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Tel_No'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'户籍变更时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'COLUMN',@level2name=N'Date'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'限制身份证长度' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_ID_Limit'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'限制性别取值' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_Sex_Limit'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'限制号码长度' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'People', @level2type=N'CONSTRAINT',@level2name=N'CK_Tel_Limit'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'身份证号关联' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Rename', @level2type=N'CONSTRAINT',@level2name=N'FK_Rename_People'
GO
USE [master]
GO
ALTER DATABASE [Manager] SET READ_WRITE
GO
3.系统实现
3.1登录业务
object Form1: TForm1
Left = 0
Top = 0
BorderStyle = bsDialog
Caption = #30331#24405#35748#35777
ClientHeight = 329
ClientWidth = 457
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
Visible = True
PixelsPerInch = 96
TextHeight = 13
object GridPanel1: TGridPanel
Left = 100
Top = 135
Width = 257
Height = 59
Align = alClient
BevelOuter = bvNone
Caption = 'GridPanel1'
ColumnCollection = <
item
Value = 29.999999999999990000
end
item
Value = 70.000000000000010000
end>
ControlCollection = <
item
Column = 0
Control = Label1
Row = 0
end
item
Column = 1
Control = Edit1
Row = 0
end
item
Column = 0
Control = Label2
Row = 1
end
item
Column = 1
Control = Edit2
Row = 1
end>
RowCollection = <
item
Value = 49.999999999999990000
end
item
Value = 50.000000000000020000
end>
ShowCaption = False
TabOrder = 0
ExplicitWidth = 254
object Label1: TLabel
Left = 0
Top = 0
Width = 77
Height = 29
Align = alClient
Caption = #29992#25143#21517#65306
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
ExplicitLeft = 51
ExplicitTop = 1
ExplicitWidth = 76
ExplicitHeight = 19
end
object Edit1: TEdit
Left = 77
Top = 0
Width = 180
Height = 29
Align = alClient
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
TabOrder = 0
ExplicitLeft = 127
ExplicitTop = 1
ExplicitWidth = 126
ExplicitHeight = 27
end
object Label2: TLabel
Left = 0
Top = 29
Width = 77
Height = 30
Align = alClient
Caption = #23494#30721#65306
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
ExplicitLeft = 70
ExplicitWidth = 57
ExplicitHeight = 19
end
object Edit2: TEdit
Left = 77
Top = 29
Width = 180
Height = 30
Align = alClient
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
PasswordChar = '*'
TabOrder = 1
ExplicitLeft = 127
ExplicitWidth = 126
ExplicitHeight = 27
end
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 457
Height = 135
Align = alTop
BevelOuter = bvNone
Caption = 'Panel1'
ShowCaption = False
TabOrder = 1
ExplicitWidth = 454
object Label3: TLabel
Left = 0
Top = 50
Width = 457
Height = 35
Align = alClient
Alignment = taCenter
Caption = #36890#29992#25143#31821#31649#29702#31995#32479
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -27
Font.Name = #38582#20070
Font.Style = []
ParentFont = False
ExplicitWidth = 224
ExplicitHeight = 27
end
object Panel5: TPanel
Left = 0
Top = 0
Width = 457
Height = 50
Align = alTop
BevelOuter = bvNone
Caption = 'Panel5'
ShowCaption = False
TabOrder = 0
ExplicitWidth = 454
end
object Panel7: TPanel
Left = 0
Top = 85
Width = 457
Height = 50
Align = alBottom
BevelOuter = bvNone
Caption = 'Panel7'
ShowCaption = False
TabOrder = 1
ExplicitTop = 91
end
end
object Panel2: TPanel
Left = 0
Top = 194
Width = 457
Height = 135
Align = alBottom
BevelEdges = []
BevelOuter = bvNone
Caption = 'Panel2'
ShowCaption = False
TabOrder = 2
ExplicitTop = 199
ExplicitWidth = 454
object Panel6: TPanel
Left = 0
Top = 0
Width = 150
Height = 25
Align = alLeft
BevelOuter = bvNone
Caption = 'Panel6'
ShowCaption = False
TabOrder = 0
ExplicitHeight = 40
end
object Panel8: TPanel
Left = 307
Top = 0
Width = 150
Height = 25
Align = alRight
BevelOuter = bvNone
Caption = 'Panel8'
ShowCaption = False
TabOrder = 1
ExplicitLeft = 322
ExplicitHeight = 40
end
object Panel9: TPanel
Left = 0
Top = 25
Width = 457
Height = 110
Align = alBottom
BevelOuter = bvNone
Caption = 'Panel9'
ShowCaption = False
TabOrder = 2
ExplicitTop = 30
end
object GridPanel2: TGridPanel
Left = 150
Top = 0
Width = 157
Height = 25
Align = alClient
BevelOuter = bvNone
Caption = 'GridPanel2'
ColumnCollection = <
item
Value = 50.000000000000000000
end
item
Value = 50.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = Button1
Row = 0
end
item
Column = 1
Control = Button2
Row = 0
end>
RowCollection = <
item
Value = 100.000000000000000000
end>
ShowCaption = False
TabOrder = 3
ExplicitLeft = 136
ExplicitTop = 48
ExplicitWidth = 185
ExplicitHeight = 41
DesignSize = (
157
25)
object Button1: TButton
Left = 0
Top = 0
Width = 78
Height = 25
Align = alClient
Caption = #30331#24405
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
TabOrder = 0
OnClick = Button1Click
ExplicitLeft = 40
ExplicitWidth = 75
end
object Button2: TButton
Left = 80
Top = 0
Width = 75
Height = 25
Anchors = []
Caption = #21462#28040
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
TabOrder = 1
OnClick = Button2Click
ExplicitLeft = 40
end
end
end
object Panel3: TPanel
Left = 0
Top = 135
Width = 100
Height = 59
Align = alLeft
BevelEdges = []
BevelOuter = bvNone
Caption = 'Panel3'
ShowCaption = False
TabOrder = 3
end
object Panel4: TPanel
Left = 357
Top = 135
Width = 100
Height = 59
Align = alRight
BevelOuter = bvNone
Caption = 'Panel4'
ShowCaption = False
TabOrder = 4
ExplicitLeft = 354
end
object ADOQuery1: TADOQuery
Connection = DataModule1.ADOConnection1
Parameters = <>
Left = 24
Top = 264
end
end
unit Login;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Data.DB,
Data.Win.ADODB;
type
TForm1 = class(TForm)
GridPanel1: TGridPanel;
Label1: TLabel;
Panel1: TPanel;
Panel2: TPanel;
Edit1: TEdit;
Panel3: TPanel;
Panel4: TPanel;
Label2: TLabel;
Edit2: TEdit;
Panel5: TPanel;
Panel7: TPanel;
Label3: TLabel;
Panel6: TPanel;
Panel8: TPanel;
Panel9: TPanel;
GridPanel2: TGridPanel;
Button1: TButton;
Button2: TButton;
ADOQuery1: TADOQuery;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Main, Connect;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
// 判断用户名或密码为空
if (Edit1.Text = '') then
begin
showMessage('错误:用户名不能为空!');
Edit1.SetFocus;
end
else
begin
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
// 尝试登录
ADOQuery1.SQL.Add(
'SELECT ''TRUE'' AS [Authorized], [Alias], [Username] FROM [Controller] WHERE [Username] = '
+ '''' + Edit1.Text + ''' AND [Password] = HASHBYTES(''MD5'', ''' +
Edit2.Text + ''')'
);
ADOQuery1.Open;
// 如果登陆成功
if (ADOQuery1.FieldByName('Authorized').AsString = 'TRUE') then
begin
// 用户是否有别名?
if (ADOQuery1.FieldByName('Alias').AsString <> '') then
begin
Form2.Label1.Caption := '欢迎您,' + trim(ADOQuery1.FieldByName('Alias').AsString)
+ '!';
end
// 否则,显示用户名
else
begin
Form2.Label1.Caption := '欢迎您,' + trim(ADOQuery1.FieldByName('Username').AsString)
+ '!';
end;
Form1.Hide;
Form2.Show;
end
else
begin
showMessage('错误:用户名或密码错误!');
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Edit1.Text := '';
Edit2.Text := '';
end;
end.
3.2主启动类
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls,
Vcl.Imaging.jpeg, Vcl.ExtCtrls;
type
TForm2 = class(TForm)
MainMenu1: TMainMenu;
F1: TMenuItem;
Q1: TMenuItem;
M1: TMenuItem;
A1: TMenuItem;
G1: TMenuItem;
N1: TMenuItem;
M2: TMenuItem;
Image1: TImage;
Label1: TLabel;
N2: TMenuItem;
N3: TMenuItem;
B1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure Q1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure G1Click(Sender: TObject);
procedure A1Click(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure M2Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure B1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Login, Edit, Rename, Move, About, Backup, Connect;
{$R *.dfm}
procedure TForm2.A1Click(Sender: TObject);
begin
Form4.Show;
end;
procedure TForm2.B1Click(Sender: TObject);
begin
Form7.Show;
Form7.FileListBox1.Directory := 'D:\Program_Files_(x64)\Git\Repos\Delphi_Design\bak';
Form7.FileListBox1.Update;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form1.Close;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
Form2.Visible := False;
end;
procedure TForm2.G1Click(Sender: TObject);
begin
Form3.Show;
end;
procedure TForm2.M2Click(Sender: TObject);
begin
Form6.Show;
Form6.ADOTable1.Close;
Form6.ADOTable1.Open;
end;
procedure TForm2.N1Click(Sender: TObject);
begin
Form5.Show;
Form5.ADOTable1.Close;
Form5.ADOTable1.Open;
end;
procedure TForm2.N3Click(Sender: TObject);
begin
Form2.Hide;
Label1.Caption := '';
Form1.Show;
Form1.SetFocus;
end;
procedure TForm2.N5Click(Sender: TObject);
begin
Form7.Show;
DataModule1.ADOConnection1.Close;
Form7.FileListBox1.Directory := 'D:\Program_Files_(x64)\Git\Repos\Delphi_Design\bak';
Form7.FileListBox1.Update;
end;
procedure TForm2.Q1Click(Sender: TObject);
begin
Form1.Close;
end;
end.
3.3部分代码
unit Rename;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB, Vcl.Grids,
Vcl.DBGrids;
type
TForm5 = class(TForm)
ADOTable1: TADOTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form5: TForm5;
implementation
uses Connect;
{$R *.dfm}
procedure TForm5.FormCreate(Sender: TObject);
begin
ADOTable1.Active := True;
end;
end.
4. 系统设计与实现
5. 结论与尚存在的问题
以下是本项目仍然存在的问题:
- 用户查询功能存在缺陷,无法在
DBGrid
中显示ADOQuery
的查询结果; - 数据库无法从
*.bak
文件中恢复。
6. 个人总结
项目由可视化集成开发环境(快速应用程序开发工具)制作而成,对比于C/C++ MFC/QT、Java Swing/SWT、Python TKinter,Delphi具有方便、快捷的优势,在界面布局方面节省了大量的时间。但在另一方面,仍有个别功能只能通过编写代码实现,大量由Delphi自动生成的Object-Pascal代码使得项目维护难度提高。
本次开发工作存在较大的失误,项目分工错误让我基本承担所有工作。此外项目的开工时间极度延后,导致工期不足,甚至无法完成基本功能。
通过此次开发的教训,在后续课程设计乃至今后的生产环境开发都要提前估计工作量与工期,合理安排开发进度,杜绝临时赶工的行为。
7. 项目用法
由于项目需要连接数据库程序,而不同设备的数据库配置可能存在差异,有别于直接连接到库文件的Microsoft Office Access、SQLite。由我使用Windows-32bit Release模式编译发布的可执行程序并不通用,所以请根据以下步骤编译运行:
- 项目提供了
Citizens_log.ldf
数据库日志文件和Citizens.mdf
数据库主文件,这2个文件仅支持Microsoft SQL Server 2017及以上版本数据库的附加。对于之前的版本,项目额外提供了script.sql
以实现数据库导入工作,此脚本最低兼容SQL Server 2008。脚本仅涉及架构,没有任何数据。如有测试需要,请在运行此脚本生成数据库后自行添加备用数据。 - 使用Delphi打开代码库中的
Manager.dproj
,定位至Connect.pas
文件的窗体设计视图。 - 修改
ADOConnection1
控件的ConnectionString
属性,点击Build
选项,在数据库连接向导切换为您设备的配置(包括驱动程序、服务器名、登陆账号及密码、数据库名)。 - 定位至
Backup.pas
文件的窗体设计视图,同样地修改ADOQuery1
控件的ConnectionString
属性。 - 定位至
Edit.pas
、Move.pas
、Rename.pas
,重新激活各个页面的ADOTable1
,确认DBGrid
能够正常显示数据库的内容。 - 以上,即可正常编译运行。