项目 6 数据存储:仿冒 SqlClient(T-SQL 转写成 SQLite)、数据库页面、DataGridView、DateTimePicker
- 每个学生一套数据库,长期保存(data/databases/<用户编号>/库名.db);学生程序运行时挂进沙箱可读写 - Sim.Data:SqlConnection / SqlCommand / SqlDataReader / SqlDataAdapter / SqlCommandBuilder / SqlParameter; 连接字符串只按库名打开学生自己的库;ScriptDom 解析 T-SQL 后按白名单转写成 SQLite 语句, STRICT 表 + 元数据表还原 SQL Server 的列类型,报错编号和中文信息与 SQL Server 一致; INSERT 不写列名时跳过自增列,日期统一格式(书上 DateTime.ToString() 拼接的日期能正确比较) - 常驻 SQL 服务(Sim.Runner sql-server):数据库页面的查询、对象资源管理器,评分前按实验 database.sql 建库 - 数据库页面(代替 SSMS):对象资源管理器、查询窗口、编辑前 200 行、表设计器、恢复实验初始数据 - DataGridView(绑定 DataView/DataTable/DataSet,单元格修改写回 DataTable)、DateTimePicker;设计器工具箱加入 - 评分:每个检查项一份新建的实验库;新增点 / 修改表格单元格、选日期、表格里有 / 没有某行的检查 - 示例:项目 6 任务 2、3;时间格式改成和中文 Windows 一致(9:05:03);异常堆栈不暴露服务器路径 - 测试:数据库端到端、接口(每人只看到自己的库、恢复实验数据)、评分出错情况、T-SQL 生成 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6b088240da
commit
670abe5921
72 files changed
+7253
-51
No files matched your search
@@ -0,0 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
// 查询结果网格(只读),和 SSMS 一样:左边是行号,NULL 显示成浅黄底的 "NULL"。
|
||||
import type { ResultSet } from './sql'
|
||||
|
||||
defineProps<{ result: ResultSet }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid-wrap">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="num" />
|
||||
<th v-for="(column, i) in result.columns" :key="i" :title="column.type ?? ''">{{ column.name || '(无列名)' }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, r) in result.rows" :key="r">
|
||||
<th class="num">{{ r + 1 }}</th>
|
||||
<td v-for="(cell, c) in row" :key="c" :class="{ null: cell === null }">{{ cell === null ? 'NULL' : cell }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="result.total > result.rows.length" class="more">共 {{ result.total }} 行,只显示前 {{ result.rows.length }} 行</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.grid-wrap {
|
||||
overflow: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.grid {
|
||||
border-collapse: collapse;
|
||||
font-size: 12px;
|
||||
font-family: "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", sans-serif;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.grid th,
|
||||
.grid td {
|
||||
border: 1px solid #d4d4d4;
|
||||
padding: 2px 6px;
|
||||
white-space: nowrap;
|
||||
max-width: 320px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.grid thead th {
|
||||
background: #f3f3f3;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.grid .num {
|
||||
background: #f3f3f3;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
min-width: 28px;
|
||||
}
|
||||
|
||||
.grid td.null {
|
||||
background: #ffffe1;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.more {
|
||||
padding: 4px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user