-
1 、概述1.1 案例介绍企业日常会议产生大量记录文本,但缺乏高效的后续跟进手段:摘要靠人工整理、任务靠口头传达、风险靠经验判断。本案例将带你从零构建一款"会议智脑"应用——上传会议记录后,自动调用华为云 MaaS 大模型(DeepSeek V4 Flash)生成摘要、提取关键决策和任务清单,并通过可视化看板、甘特图、日历等多维度视图进行任务追踪与风险预警。1.2 适用对象企业开发者个人开发者1.3 案例时间 本案例总时长预计60分钟。1.4 案例流程 1. 领取华为云 MaaS 平台大模型 Tokens,获取 API Key 和模型接入地址; 2. 配置 .env 环境变量,将 MaaS API Key 等信息写入配置; 3. 初始化数据库并启动后端服务,验证 API 文档可访问; 4. 启动前端开发服务器,登录系统并上传会议记录,体验 AI 自动生成摘要与任务提取; 5. 在任务看板、甘特图、日历等视图中查看和管理提取的任务,触发风险检测。1.5 资源总览 本案例使用的华为云服务均为按需付费,预计花费不超过50元(MaaS Tokens 代金券可覆盖)。体验完成后请及时释放资源,避免产生多余的费用。资源名称规格单价(元) 华为云 MaaSDeepSeek V4 Flash 大模型推理服务代金券可覆盖华为云码道(CodeArts)代码智能体通用体验版免费2 、环境和资源准备2.1 领取华为云MaaS平台大模型Tokens福利 方式一: 登录华为开发者空间,参考案例《华为开发者空间 - ModelArts Studio大模型通用代金券领取使用指导》中的“二、 开通MaaS平台大模型”章节内容领取代金券,获取到模型的API地址、模型名称和API Key。 方式二: 登录华为开发者空间,参考案例《华为云MaaS平台大模型Tokens领取使用指导》中的“二、 领取MaaS平台大模型Tokens”章节内容,领取MaaS平台DeepSeek V3系列大模型Tokens代金券,购买ModelArts Studio DeepSeek Tokens套餐包,开通模型服务,最后获取到模型的API地址、模型名称和API Key。 2.2 安装本地开发环境本案例需要以下开发工具: 工具版本要求用途Python≥ 3.11后端运行时Node.js≥ 18.0前端构建npm≥ 9.0前端包管理Git≥ 2.30版本控制3 、构建会议智脑应用3.1 部署项目代码1)项目结构说明:ai-meeting/├── app/│ ├── core/ # 核心基础设施│ │ ├── config.py # Pydantic Settings 配置管理│ │ ├── database.py # 异步数据库引擎 + 会话工厂│ │ ├── exceptions.py # 统一异常处理器│ │ └── logging.py # 日志配置│ ├── models/ # SQLAlchemy ORM 模型│ │ ├── user.py # 用户模型│ │ ├── meeting.py # 会议模型│ │ ├── task.py # 任务模型│ │ └── risk_alert.py # 风险预警模型│ ├── schemas/ # Pydantic 请求/响应 Schema│ ├── api/ # FastAPI 路由│ │ ├── auth.py # 认证 + 用户管理 API│ │ ├── meetings.py # 会议 CRUD + 搜索 + 导出│ │ ├── tasks.py # 任务列表 + 更新 + 排序│ │ └── skill.py # 风险检测 API│ ├── services/ # 业务逻辑层│ │ ├── auth_service.py # 注册/登录/JWT/密码哈希│ │ ├── meeting_service.py # 会议业务逻辑│ │ ├── task_service.py # 任务业务逻辑│ │ └── maas_service.py # MaaS API + 本地摘要引擎│ └── main.py # FastAPI 应用入口├── frontend/│ ├── package.json # 前端依赖│ ├── vite.config.js # Vite 配置(API 代理)│ └── src/│ ├── main.js # 入口(ElementPlus 中文 locale)│ ├── App.vue # 布局(侧边栏 + 路由 + 登录状态)│ └── components/ # 12 个功能组件├── .env # 环境变量├── requirements.txt # Python 依赖└── init_db.py # 数据库初始化脚本 2)下载源码 通过git下载源码到本地(含demo演示),代码仓地址:ai-meeting - AtomGitgit clone https://gitcode.com/ gcw_Xpooy7x3/ai-meeting.gitcd ai-meeting 3)关键代码讲解 3.1 配置管理——从 .env 加载 MaaS API Key 使用 Pydantic Settings 从 .env 文件加载配置,extra: "ignore" 允许旧变量不报错,@lru_cache 实现全局单例:from pydantic_settings import BaseSettingsfrom functools import lru_cacheclass AppSettings(BaseSettings): DATABASE_URL: str = "sqlite+aiosqlite:///./ai_meeting.db" REDIS_URL: str = "redis://localhost:6379/0" MAAS_API_KEY: str = "" MAAS_API_URL: str = "https://api.modelarts-maas.com/v2/chat/completions" MAAS_MODEL: str = "deepseek-v4-flash" APP_NAME: str = "会议智脑" DEBUG: bool = False JWT_SECRET: str = "change-me-in-production" JWT_ALGORITHM: str = "HS256" JWT_EXPIRE_MINUTES: int = 1440 model_config = { "env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore", }@lru_cache()def get_settings() -> AppSettings: return AppSettings() 在项目根目录创建 .env 文件,将 MaaS 的 API Key、API 地址和模型名称填入:DATABASE_URL=sqlite+aiosqlite:///./ai_meeting.dbREDIS_URL=redis://localhost:6379/0MAAS_API_KEY=<你的华为云MaaS API Key>MAAS_API_URL=https://api.modelarts-maas.com/v2/chat/completionsMAAS_MODEL=deepseek-v4-flashAPP_NAME=会议智脑DEBUG=trueJWT_SECRET=meeting-brain-jwt-secret-2026 3.2 核心逻辑——调用华为云 MaaS 大模型生成摘要 这是本案例的核心代码。process_meeting 函数实现多级降级策略:优先调用 MaaS API,失败时降级到本地规则引擎。同时支持 Redis 缓存(可选,连接失败自动跳过)。 System Prompt 设计——明确指定英文字段名和 JSON 输出格式,避免模型返回中文键名:SYSTEM_PROMPT = """你是一个严谨的会议纪要专家。请处理输入的会议记录并输出JSON。规则:- summary:不超过150字,仅包含最终结论,不重复会议过程- key_decisions:只提取有明确结论或投票通过的事项,最多5条- tasks:仅当原文明确提及"某人负责某事"或"需要在某时间前完成"时才提取,严禁臆造- 日期格式统一为 YYYY-MM-DD,如果原文没有年份则默认为当前年份- 如果原文信息不足,对应字段返回空列表或空字符串,不要编造输出必须是合法JSON,严格使用以下英文字段名(禁止使用中文字段名):{ "summary": "一句话摘要", "key_decisions": ["决策1", "决策2"], "tasks": [ {"description": "任务描述", "assignee": "责任人", "deadline": "YYYY-MM-DD", "priority": "high/mid/low"} ]}""" MaaS API 调用——使用 httpx.AsyncClient 异步调用,指数退避重试(最多3次,仅对超时/连接错误重试),超时时间90秒:async def _call_maas_api(record_text: str) -> dict: settings = get_settings() headers = { "Authorization": f"Bearer {settings.MAAS_API_KEY}", "Content-Type": "application/json", } body = _build_request_body(record_text) for attempt in range(1, MAX_RETRIES + 1): try: async with httpx.AsyncClient(timeout=90) as client: resp = await client.post(settings.MAAS_API_URL, headers=headers, json=body) if resp.status_code != 200: raise AppException(502, f"MaaS 接口返回错误码: {resp.status_code}") content = resp.json()["choices"][0]["message"]["content"] start, end = content.find("{"), content.rfind("}") + 1 parsed = json.loads(content[start:end]) # 兼容中文键名 if "摘要" in parsed and "summary" not in parsed: parsed["summary"] = parsed.pop("摘要") if "关键决策" in parsed and "key_decisions" not in parsed: parsed["key_decisions"] = parsed.pop("关键决策") if "任务清单" in parsed and "tasks" not in parsed: parsed["tasks"] = parsed.pop("任务清单") raw_tasks = parsed.get("tasks") or parsed.get("task_list") or parsed.get("action_items") or [] normalized_tasks = [] for t in raw_tasks: if isinstance(t, dict): nt = { "description": t.get("description") or t.get("task") or t.get("任务") or "", "assignee": t.get("assignee") or t.get("person") or t.get("负责人") or "", "deadline": t.get("deadline") or t.get("due_date") or t.get("截止日期") or "", "priority": t.get("priority") or "mid", } normalized_tasks.append(nt) elif isinstance(t, str): m = re.match(r"^([\u4e00-\u9fa5]{2,4})[::]\s*(.+)$", t) if m: assignee, desc = m.group(1), m.group(2) normalized_tasks.append({"description": desc, "assignee": assignee, "deadline": "", "priority": "mid"}) parsed["tasks"] = normalized_tasks return parsed except (httpx.TimeoutException, httpx.ConnectError): wait = 2 ** attempt await asyncio.sleep(wait) raise AppException(502, "MaaS 调用失败") 多级降级与缓存——完整的 process_meeting 流程:async def process_meeting(record_text: str) -> dict: if not record_text or not record_text.strip(): return {"summary": "", "key_decisions": [], "tasks": []} settings = get_settings() if not settings.MAAS_API_KEY: return _local_summarize(record_text) redis_client = await _get_redis() try: if redis_client: cached = await redis_client.get(_cache_key(record_text)) if cached: return json.loads(cached) try: result = await _call_maas_api(record_text) except Exception: result = _fallback_result(record_text) if redis_client: await redis_client.set(_cache_key(record_text), json.dumps(result, ensure_ascii=False), ex=7*24*3600) return result finally: if redis_client: await redis_client.close()3.3 会议上传与 AI 处理联动 会议上传 API 在创建记录后,自动调用 process_meeting 进行 AI 处理,将生成的摘要、决策写入 Meeting 记录,并将提取的任务批量创建为 Task 记录:class MeetingService: def __init__(self, db: AsyncSession): self.db = db async def upload_meeting(self, title, record_text, tags=None): meeting = Meeting(title=title, record_text=record_text, status=MeetingStatus.pending, tags=tags) self.db.add(meeting) await self.db.flush() if record_text and record_text.strip(): await self._process_meeting_content(meeting) return meeting.id async def _process_meeting_content(self, meeting): try: result = await process_meeting(meeting.record_text) meeting.summary = result.get("summary", "") meeting.key_decisions = result.get("key_decisions", []) meeting.status = MeetingStatus.processed for task_data in result.get("tasks", []): task = Task( meeting_id=meeting.id, description=task_data.get("description", ""), assignee=task_data.get("assignee", ""), deadline=self._parse_date(task_data.get("deadline")), priority=self._parse_priority(task_data.get("priority")), status=TaskStatus.todo, ) self.db.add(task) await self.db.flush() except Exception as exc: logger.error(f"会议处理失败,保持pending状态: {exc}")3.4 数据库会话管理——SQLite 异步适配 SQLite 适配关键点:WAL 模式支持并发读、外键约束、不使用连接池。get_db() 通过 yield 实现请求级会话,自动 commit/rollback:from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSessionfrom sqlalchemy import eventsettings = get_settings()_is_sqlite = settings.DATABASE_URL.startswith("sqlite")engine = create_async_engine(settings.DATABASE_URL, echo=settings.DEBUG)if _is_sqlite: @event.listens_for(engine.sync_engine, "connect") def _set_sqlite_pragma(dbapi_conn, connection_record): cursor = dbapi_conn.cursor() cursor.execute("PRAGMA journal_mode=WAL") cursor.execute("PRAGMA foreign_keys=ON") cursor.close()AsyncSessionLocal = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)async def get_db() -> AsyncSession: async with AsyncSessionLocal() as session: try: yield session await session.commit() except Exception: await session.rollback() raise3.5 前端 Vite 代理配置 开发环境将 /api 请求代理到后端 8000 端口:import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'export default defineConfig({ plugins: [vue()], server: { proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true }, '/health': { target: 'http://localhost:8000', changeOrigin: true }, }, },})4)运行调试 步骤1:安装后端依赖pip install -r requirements.txt 步骤2:安装前端依赖cd frontendnpm installcd .. 步骤3:初始化数据库python init_db.py 执行成功后输出:数据库表创建完成示例数据初始化完成!2个用户 + 3个会议 + 10项任务 管理员: admin / admin123 普通用户: demo / demo123 步骤4:启动后端服务uvicorn app.main:app --reload --port 8000 启动后访问 http://localhost:8000/docs 可查看自动生成的 OpenAPI 交互式文档: 步骤5:启动前端开发服务器cd frontendnpm run dev 启动后访问 http://localhost:5173,进入登录页面: 步骤6:登录并体验完整功能 使用 admin / admin123 登录,进入数据总览页面: 点击左侧菜单"上传会议",粘贴会议记录文本,点击"提交会议记录": 上传成功后点击"查看详情",查看 AI 自动生成的摘要、关键决策和任务清单: 切换到"任务看板"页面,拖拽卡片切换任务状态: 切换到"任务甘特图"页面,查看任务时间线: 切换到"风险检测"页面,点击"立即检测": 4 、释放资源本案例使用本地 SQLite 数据库和可选 Redis,不涉及华为云付费资源的持续占用。如需释放:• 删除本地 ai_meeting.db 文件即可清除所有数据• 如使用了华为云 MaaS Tokens 代金券,代金券到期后自动失效,无需手动释放5 、扩展资料说明• 想了解更多关于华为云 MaaS 大模型服务的可以访问:https://support.huaweicloud.com/productdesc-maas/maas_01_0001.html• 想了解更多关于 FastAPI 框架的可以访问:https://fastapi.tiangolo.com/• 想了解更多关于 Vue 3 组合式 API 的可以访问:https://cn.vuejs.org/guide/introduction.html• 想了解更多关于 Element Plus 组件库的可以访问:https://element-plus.org/zh-CN/
-
SQLite 和 TinyDB 技术文档一、SQLite1. 特性轻量级:SQLite 是一个轻量级的嵌入式数据库,无需独立的服务器进程,可以直接集成到应用程序中。跨平台:支持多种操作系统,包括 Windows、Linux、macOS 等。关系型数据库:使用 SQL 语言进行数据操作,支持表、索引、视图等关系型数据库的特性。事务支持:提供事务处理功能,确保数据的一致性和完整性。2. 应用场景小型应用程序:适用于小型桌面应用、移动应用和嵌入式系统等,对数据库性能要求不高的场景。临时数据存储:可以作为临时数据存储的解决方案,例如在数据处理过程中存储中间结果。单用户应用:对于单用户的应用程序,SQLite 是一个简单而有效的数据库选择。3. 简单使用安装:通常无需安装,许多编程语言都内置了对 SQLite 的支持。创建数据库和表:import sqlite3# 连接到数据库,如果数据库不存在,则会自动创建conn = sqlite3.connect('example.db')# 创建一个游标对象c = conn.cursor()# 创建一个表c.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)''')# 提交更改conn.commit()# 关闭连接conn.close()插入数据:import sqlite3conn = sqlite3.connect('example.db')c = conn.cursor()# 插入一条数据c.execute("INSERT INTO users (name, age) VALUES ('Alice', 30)")# 提交更改conn.commit()conn.close()查询数据:import sqlite3conn = sqlite3.connect('example.db')c = conn.cursor()# 查询所有数据c.execute("SELECT * FROM users")rows = c.fetchall()for row in rows: print(row)conn.close()4. 高级使用索引:可以为表中的列创建索引,提高查询性能。import sqlite3conn = sqlite3.connect('example.db')c = conn.cursor()# 为 name 列创建索引c.execute("CREATE INDEX idx_name ON users (name)")conn.commit()conn.close()事务处理:可以使用事务来确保数据的一致性。import sqlite3conn = sqlite3.connect('example.db')c = conn.cursor()try: # 开始事务 conn.execute("BEGIN") # 执行多个数据库操作 c.execute("INSERT INTO users (name, age) VALUES ('Bob', 25)") c.execute("INSERT INTO users (name, age) VALUES ('Charlie', 35)") # 提交事务 conn.commit()except Exception as e: # 回滚事务 conn.rollback()finally: conn.close()存储过程和函数:可以创建存储过程和函数,提高数据库的可维护性和可扩展性。import sqlite3conn = sqlite3.connect('example.db')c = conn.cursor()# 创建一个存储过程c.execute("CREATE PROCEDURE add_user(name TEXT, age INTEGER) BEGIN INSERT INTO users (name, age) VALUES (name, age); END")# 调用存储过程c.execute("CALL add_user('David', 40)")conn.commit()conn.close()二、TinyDB1. 特性轻量级:TinyDB 是一个轻量级的 NoSQL 数据库,适用于小型项目和临时数据存储。纯 Python 实现:无需安装额外的数据库服务器,易于部署和使用。文档型数据库:以 JSON 格式存储数据,每个文档都是一个独立的 JSON 对象。简单易用:提供了简单的 API,易于学习和使用。2. 应用场景小型项目:适用于小型的 Python 项目,例如脚本、工具和小型 Web 应用等。临时数据存储:可以作为临时数据存储的解决方案,例如在数据处理过程中存储中间结果。测试和原型开发:在测试和原型开发阶段,TinyDB 可以快速搭建一个简单的数据库环境。3. 简单使用安装:可以使用 pip 安装 TinyDB。pip install tinydb创建数据库和表:from tinydb import TinyDB# 创建一个数据库db = TinyDB('example.json')# 创建一个表table = db.table('users')插入数据:from tinydb import TinyDBdb = TinyDB('example.json')table = db.table('users')# 插入一条数据table.insert({'name': 'Alice', 'age': 30})查询数据:from tinydb import TinyDB, Querydb = TinyDB('example.json')table = db.table('users')# 查询所有数据rows = table.all()for row in rows: print(row)# 查询特定条件的数据User = Query()result = table.search(User.name == 'Alice')print(result)4. 高级使用索引:TinyDB 不支持传统的数据库索引,但可以通过使用自定义的查询函数来实现类似的功能。from tinydb import TinyDB, Querydb = TinyDB('example.json')table = db.table('users')def search_by_name(name): return table.search(Query().name == name)result = search_by_name('Alice')print(result)事务处理:TinyDB 不提供事务处理功能,但可以通过手动管理数据的插入、更新和删除操作来实现类似的效果。from tinydb import TinyDBdb = TinyDB('example.json')table = db.table('users')try: # 插入数据 table.insert({'name': 'Bob', 'age': 25}) table.insert({'name': 'Charlie', 'age': 35})except Exception as e: # 发生错误时,手动回滚操作 table.remove(Query().name == 'Bob') table.remove(Query().name == 'Charlie')finally: db.close()存储过程和函数:TinyDB 不支持存储过程和函数,但可以通过定义自定义的 Python 函数来实现类似的功能。from tinydb import TinyDBdb = TinyDB('example.json')table = db.table('users')def add_user(name, age): table.insert({'name': name, 'age': age})add_user('David', 40)三、总结SQLite 和 TinyDB 都是轻量级的数据库解决方案,适用于不同的应用场景。SQLite 是一个关系型数据库,适用于需要使用 SQL 语言进行数据操作的场景;TinyDB 是一个文档型 NoSQL 数据库,适用于需要快速搭建简单数据库环境的场景。在选择数据库时,需要根据具体的需求和应用场景来进行选择。———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/wu73guang5jian/article/details/144575134
-
一、了解业务负载首先,需要深入了解业务负载特性,包括:数据访问模式:是读多写少,还是写多读少?查询类型:是范围查询、点查询还是聚合查询?数据大小和增长趋势:数据量有多大?未来预计如何增长?访问频率:哪些数据被频繁访问?二、选择合适的分片键根据业务负载特性选择合适的分片键是关键步骤。常见的分片键选择策略包括:范围分片:适用于按时间序列或地理位置等有明确范围的数据。哈希分片:适用于均匀分布的负载,可以平衡各个分片的数据量。列表分片:适用于某些特定的枚举值作为分片键。三、监控和分析使用GAUSSDB提供的监控工具(如SQL诊断、慢查询日志等)来监控当前分片策略的性能。重点关注:性能瓶颈:确定哪些分片是性能瓶颈。数据分布:检查数据是否均匀分布在各个分片上。四、调整分片策略基于监控和分析结果,调整分片策略。可能的调整包括:重新分片:如果发现某些分片负载过高或数据分布不均,可以考虑重新分片。修改分片键:如果当前分片键不再适用,可以修改分片键。增加或减少分片数量:根据业务增长或缩减的需求,动态调整分片的数量。五、利用自动化和智能化工具GAUSSDB提供了自动化和智能化工具来帮助管理分片策略,如:自动负载均衡:系统自动平衡各个分片的负载。智能查询优化器:优化查询执行计划,减少查询延迟。六、定期审查和优化定期审查数据库性能和业务需求变化,进行必要的优化。包括:定期评估:每季度或每半年评估一次数据库性能和业务需求。灵活调整:根据评估结果灵活调整分片策略。七、保持良好的文档记录记录每次的分片策略调整和优化措施,以便未来参考和复盘。这有助于追踪分片策略的变化,理解每次调整的背景和目的,从而在未来的优化工作中提供有价值的参考。综上所述,通过深入了解业务负载、选择合适的分片键、监控和分析性能、调整分片策略、利用自动化和智能化工具、定期审查和优化以及保持良好的文档记录等步骤,可以有效地根据实际业务负载动态优化GAUSSDB的数据分片策略。
-
一、行级锁的基本概念行级锁允许其他事务并发地访问未被锁定的行,从而提高了数据库的并发性能。在高并发的场景中,行级锁能够显著减少锁冲突,使得多个事务可以同时操作不同的数据行。二、行级锁的类型MySQL中的行级锁主要包括以下几种类型:记录锁(Record Lock):直接锁定被操作的数据行。分为共享锁(S锁)和排他锁(X锁)。S锁允许其他事务读取被锁定的数据行,但不允许修改;X锁则不允许其他事务读取或修改被锁定的数据行。间隙锁(Gap Lock):锁定一个范围,但不包括该范围内的任何实际数据记录。主要用于阻止其他事务在锁定数据范围内插入新数据,防止幻读现象的发生。只存在于可重复读(Repeatable Read)隔离级别。临键锁(Next-Key Lock):记录锁和间隙锁的组合,锁定一个范围并包括边界上的记录。防止其他事务在范围内插入新记录或修改被锁定的记录。只在可重复读或更高隔离级别下生效。三、行级锁的实现原理MySQL的行级锁是通过给索引项加锁来实现的。这意味着,只有通过索引条件来检索数据,才能使用行级锁;否则,将退化为使用表级锁。因此,合理设计表的索引对行级锁的有效性至关重要。四、行级锁的使用场景行级锁适用于高并发、细粒度的操作场景。例如,在电商系统中,用户同时下单时可能会操作相同的库存数据,此时行级锁能够避免库存数据的冲突和不一致。五、行级锁的优缺点优点:高并发性:不同事务可以同时锁定不同行,提高了数据库的并发性能。精确控制:只锁定需要操作的行,避免了无谓的锁竞争,降低了锁冲突的概率。缺点:内存消耗:行锁需要维护每一行的锁信息,会占用一定的内存空间。性能开销:锁管理的细粒度导致了额外的性能开销,例如死锁检测等。当大量事务同时访问不同行时,仍然可能出现锁竞争问题。六、行级锁的死锁问题行级锁在支持高并发的同时,也可能引发死锁。死锁发生时,两个或多个事务相互等待对方持有的锁,从而导致所有事务都无法继续执行。MySQL的InnoDB存储引擎具有死锁检测机制,会自动回滚某个事务以解决死锁问题。但开发者仍需注意避免复杂事务中可能的死锁情况,例如可以通过增加冗余字段或使用缓存来减少数据库的锁定需求,从而提升并发性能。综上所述,MySQL的行级锁是一种细粒度的锁机制,适用于高并发、细粒度的操作场景。通过合理使用行级锁,可以显著提高数据库的并发性能和数据一致性。但开发者也需要注意行级锁可能带来的内存消耗、性能开销以及死锁问题,并采取相应的优化措施。
-
【问题来源】 重庆银行(易云)【问题简要】 IVR以GSL的方式开发,只放音不收号的cell需要使用哪个cell怎么配置【问题类别】【必填】 IVR-GSL【AICC解决方案版本】【必填】 AICC可选择版本:AICC 23.200 【UAP可选择版本:V300R001C02SPC109】 【CTI可选择版本:V300R008C25SPC019】【期望解决时间】 尽快【问题现象描述】【必填】 IVR以GSL的方式开发,只放音不收号(也就是放音的时候不被打断)的cell需要使用哪个cell怎么配置
-
Sqlite3 数据库介绍SQLite 是一个轻量级的数据库,它将整个数据库存储在一个磁盘文件中。SQLite 数据库具有以下特点:轻量级:SQLite 的数据库引擎只有一个动态链接库(libsqlite3),无需额外安装其他组件。高效性:SQLite 使用了高效的磁盘存储格式和索引技术,具有较好的性能。对于小规模的应用,SQLite 可以在内存中管理数据,进一步提高性能。跨平台:SQLite 支持多种操作系统,如 Windows、Linux、macOS 等,并且可以在不同的编程语言中使用。易于使用:SQLite 提供了简单的 API,方便开发者快速上手。数据库自给自足:SQLite 数据库包含了完整的 SQL 解析器、编译器和解释器,无需额外依赖其他数据库服务器。支持 SQL 标准:SQLite 支持大部分 SQL 92 标准,提供了丰富的 SQL 功能。开源免费:SQLite 是开源的,可以免费使用,适用于各种商业和非商业项目。。环境搭建SQLite 数据库是一个轻量级的数据库,它不需要额外安装。SQLite 数据库已经内置在许多操作系统和编程语言中,因此通常可以直接使用。 对于 Python 来说,你可以通过以下方式在命令行中检查 SQLite 是否已经内置:python -m sqlite3 如果输出 SQLite 版本信息,那么说明 Python 已经内置了 SQLite 数据库。然而,在某些情况下,你可能需要安装特定的 SQLite 版本或者相关工具。例如,在 Windows 上,你可以下载预编译的二进制文件并解压到指定目录,然后将该目录添加到系统环境变量中。在 Linux 和 macOS 上,你可以通过编译源代码来安装特定版本的 SQLite。注意:虽然 SQLite 数据库本身不需要安装,但你可能需要为特定编程语言的 SQLite 绑定(如 Python 的 sqlite3 模块)编写额外的代码或脚本。这些绑定库可能需要根据实际需求进行安装或配置。Python 操作Sqlite3 代码实战Python 操作 SQLite 数据库,可以使用内置的sqlite3模块。以下是一个简单的示例,展示了如何连接到 SQLite 数据库、创建表、插入数据和查询数据。首先,确保你已经安装了 SQLite 数据库。如果尚未安装,可以使用以下命令安装:pip install pysqlite3 接下来,看一个简单的 Python 代码示例:import sqlite3 # 连接到数据库(如果不存在,将创建一个名为 test.db 的文件) conn = sqlite3.connect('test.db') # 创建一个游标对象 cursor = conn.cursor() # 创建一个名为 users 的表 cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, age INTEGER NOT NULL ) ''') # 插入数据 cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30)) cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 25)) # 提交事务 conn.commit() # 查询数据 cursor.execute("SELECT * FROM users") rows = cursor.fetchall() # 打印查询结果 for row in rows: print(row) # 关闭游标和连接 cursor.close() conn.close() 这个示例首先连接到名为test.db的 SQLite 数据库(如果不存在,则创建一个)。然后创建一个名为users的表,包含id、name和age三个字段。接着插入两条数据,并查询所有数据并打印。运行上述代码,你将看到以下输出:(1, 'Alice', 30) (2, 'Bob', 25) 这表明数据已成功插入并从数据库中查询出来。注意:在实际应用中,为了确保数据安全和一致性,建议在使用完数据库后,始终关闭游标和连接。如本示例所示。
-
SQLite 开发团队于 2023 年 08 月 24 日发布了 SQLite 3.43.0 版本。本文给大家分析一下该版本的更新。全文索引SQLite 3.43.0 增加了 Contentless-Delete FTS5 索引。这是一种 FTS5 全文索引的变种,不存储被索引的内容,同时支持数据的删除操作。例如:CREATE VIRTUAL TABLE f1 USING fts5(a, b, c, content='', contentless_delete=1); 1Contentless-delete 表与 Contentless 表的区别在于: Contentless-delete 表支持 DELETE 以及 INSERT OR REPLACE INTO 语句; Contentless-delete 表支持 UPDATE 语句,前提是所有用户定义的字段都指定了新的数据; Contentless-delete 表不支持 FTS5 删除命令。例如:-- 支持以下 UPDATE 语句UPDATE f1 SET a=?, b=?, c=? WHERE rowid=?;-- 不支持以下 UPDATE 语句,因为字段 c 没有指定新的数据UPDATE f1 SET a=?, b=? WHERE rowid=?; 1 2 3 4 5除非存在旧版本的后向兼容需求,推荐使用 Contentless-delete 表。日期时间函数新版本增强了日期时间相关的函数。首先是增加了“±YYYY-MM-DD HH:MM:SS.SSS”形式的时间偏移量,例如:select date('2023-01-01', '+1000-01-01');3023-02-02 1 2其次,新版本增加了 timediff(A, B) 函数,计算从时间 B 到达时间 A 所需的时间。例如:select timediff('2023-06-01', '2023-01-01');+0000-05-00 00:00:00.000 1 2timediff() 函数返回的格式是字符串,方便阅读。如果想要返回精确的时间差(天数、秒数等),可以使用两个 julianday() 或 unixepoch() 函数相减。字符串函数SQLite 3.43.0 增加了一个 octet_length(X) 字符串函数,用于返回字符串 X 占用的字节数。例如:select octet_length('Hello');5select octet_length('你好');6 1 2 3 4 5octet_length(X) 以字节为单位,而不是字符为单位。因此,不同数据库字符集可能返回不同的长度。C 语言接口SQLite 3.43.0 新增了一个 sqlite3_stmt_explain(S,E) API,用于改变预编译语句的 EXPLAIN 设置。如果参数 E 设置为 0,S 就是一个普通的预编译语句;如果 E 设置为 1,S 就变成一个以 EXPLAIN 开始的 SQL 语句;如果E 设置为 2,S 就变成一个以 EXPLAIN QUERY PLAN 开始的 SQL 语句。查询优化查询优化器增强包括: LEFT JOIN 强度削减优化扩展至 RIGHT JOIN 以及 FULL JOIN,并且重命名为 OUTER JOIN 强度消减优化。 改进了 OUTER JOIN 强度消减优化使用的理论证明器,减少了假阴性的情况。Decimal 扩展新版本增强了与 decimal 扩展相关的内容: 新增函数 decimal_pow2(N),返回 2.0 的 N 次方,N 为 -2000 到 +2000 之间的整数; 新增函数 decimal_exp(X),以科学计数法形式(e+NN)返回 X 的十进制数字; 对于浮点数 X,decimal(X) 函数将会返回完全扩展的精确数字。例如:select decimal_pow2(10);+1.024e+03select decimal_exp(12.3);+1.2300000000000000710542735760100185871124267578125e+01select decimal(12.3);12.300000000000000710542735760100185871124267578125 1 2 3 4 5 6 7 8JSON 性能某些情况下,对于大型 JSON 字符串的处理性能获得翻倍提升。————————————————版权声明:本文为CSDN博主「不剪发的Tony老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/horses/article/details/132535127
-
一、SQL基本语句1. 创建表:至少需要包含一个表名和一个字段名,创建基本表: CREATE TABLE stu (id int, name text, score real); 基本表会在数据库中永久存在。创建临时表:CREATE TEMP TABLE stu (id int, name text, score real); 临时表是暂时存活,一旦连接断开就会自动销毁。字段解析:stu:表名id/name/score:字段名int/text/real:类型SQLite有五种类型:integer、real、text、blob、null。创建表允许在字段后添加约束:CREATE TABLE stu (id int primary key, name text, score real); 为字段id添加主键。2. 修改表:修改表的结构增加一个无初始值字段:alter table stu add column <字段名> <类型>;增加一个有初始值字段:alter table stu add column <字段名> <类型> default value;修改表名:alter table <tablename_old> rename to <tablename_new>3. 数据库查询:select是SQL中最大、最复杂的命令。最常见的select命令由 select、from、where组成: select * from <table_name>;1.关系操作:大部分SQL实现中,select语句提供了混合、比较、过滤数据的“关系操作”。通常分为以下三类。 基本操作:限制、投影、笛卡儿积、联合、差、重命名。基本操作定义了基础的关系操作 附加操作:交叉、自然连接、赋值。附加操作提供了频繁操作的快速方式,由基本操作组成。 扩展操作:广义投影、左外连接、右外连接、全外连接。扩展操作对基本操作和附加操作的扩展。 所有这些操作都定义在关系中,也就是我们说的表。他们将一个或多个关系操作作为输入,然后产生另一个关系的输出。如: select name from(select name, id from(select *from stu)); 最里层的输出作为次里层的输入,次里层的输出作为最外层的输入。2.select命令与管道操作select命令用一系列子句将很多关系操作组合在一起,每个子句代表一种特定的关系操作。select [distinct] heading from tables where predicate group by columns having predicates order by columns limit count,offset;在这里插入图片描述3.过滤:where是一个过滤器值:真实的数字(1,2,3)或者字符串(“xxxxx”)。操作符:一个或多个值作为输入产生一个新值作为输出。二元操作符:算术操作符:+ - * / :输入数值产生一个数值关系操作符:< > = :比较值和值产生一个逻辑结果逻辑操作符:AND OR NOT IN:根据输入产生具体真假值 如:(x > 5)AND (y < 2)LIKE与GLOB操作符:用于匹配通配符指定模式的文本,匹配成功返回查找到的内容,glob区分大小写 like: %_ where salary like ‘200%’ 查找以200开头的任意值 where salary like ‘%200%’ 查找任意位置包含200的任意值 where salary like ‘00%’ 查找第二位和第三位为00的任意值 where salary like '2%_%’ 查找以2开头、且长度至少为3个字符的任意值 where salary like ‘%2’ 以2结尾的任意值 where salary like ‘_2%3’ 查找第二位为2,且以3结尾的任意值 where salary like ‘2___3’ 查找长度为5,且以2开头以3结尾的任意值。 例子:select * from company where age Like '2%'; 1 glob: ? where salary glob '200’ 查找以200开头的任意值 where salary glob ‘200’ 查找任意位置包含200的任意值 where salary glob ‘?00*’ 查找第二位和第三位为00的任意值 where salary glob ‘2??’ 查找以2开头、且长度至少为3个字符的任意值 where salary glob ‘2’ 以2结尾的任意值 where salary glob '?23’ 查找第二位为2,且以3结尾的任意值 where salary glob ‘2???3’ 查找长度为5,且以2开头以3结尾的任意值。 例子:select * from company where age glob '2*'; 14. 限定和排序:使用limit和offset关键字限定结果集的大小和范围。limit限定返回记录最大数,offset指定偏移量。例子:从id的第三位提取三个记录。desc降序 asc升序(默认)select *from company order by id limit 3 offset 2; 15. 函数和聚合:SQLite提过了很多函数和聚合,可用在不同的子句中,如:计算绝对值(abs()),字符串格式函数,字符串大小写转化(upper(),lower())。例子:select id, upper(name),length(name) from company where length(name)<5; 1聚合:是一类特殊的函数如:sum()、count()、avg()、min()、max()。例子:select count(*) from company; 16. 分组:group by:把集合分为多个组例子:select id count(*) from company group by id; 1约束:having 对group by起到了约束作用,having对每个组应用过滤,通过过滤的组传递给select子句做聚合和映射。having子句必须出现在group by 子句之后,order by之前。例子:select *from company group by name having count(age>20); 查找年纪大于20岁的记录 17.去重:distinct与select一起使用,消除重复记录,只获取唯一一次的记录。例子:select distinct name from company; 18.多表连接:连接(join)是多表数据工作的关键,它的输出作为其他子句的输入。一个表中字段的值与另一个表中字段值对应,这样就存在了关联。要实现连接,数据库需要找到匹配的行,对于第一个表的每一行,数据库都要查询第二个表的所有行,寻找那些连接字段具有相同值得行。然后将他们包含的输入关系中。 内连接:通过表中两个字段进行连接。内连接使用关系代数中一种集合操作-交叉。找出同时存在两个集合的相同元素。 例子:select * from foods inner join food_types on foods.id = food_types.id; 1 交叉连接:两个表之间没有任何联系,强制将他们连在一起,称为交叉连接或笛卡尔积。两个表之间行与行之间没有联系没有连接,只是简单组合在一起。 外连接:外连接选择内连接的所有行外加一些关系之外的行。外连接有三种:左外连接、右外连接、全外连接。 自然连接:通过表中共有的字段名称将两个表连接起来。自然连接会连接两个表中具有相同名称的字段。9.别名:如果表名很长的话可以简化对表重命名例子: select foods.name, food_types.name from foods, food_types where foods.type_id = food_types.id limit 10; select f.name, t.name from foods f, food_types t where f.type_id = t.id limit 10; 1 210.子查询:子查询是指select语句中嵌套select语句。11.复合查询与子查询相反,它是使用三种特殊的关系操作符(联合、交叉连接和差集)处理多个查询结果。对应关键字:union、intersect和except。1.涉及的关系的字段数目必须相等。2. 只能有一个oder by 子句,并且在复合查询的末尾处,对联合结果进行排序。3.union子句:操作输入的两个关系:A和B,将A和B联合成只包含A和B中非重复字段的单一关系。如果想保留重复数据则使用union all。例子:SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID UNION SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID; 14.except子句:找出在A但不在B的行。例子:SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID except SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID; 112.NULL:未知的、不可知的特殊占位符,不是真、不是假、不是空、不是零。二、SQL高级语句1.修改数据:insert、update、delete。1.插入记录:insert:向表中插入数据:insert into <table_name> values(value1, value2, …);例子:insert into stu values(1, 'ZhangSan', 89.9); //插入整条数据 insert into stu(id, name) values(5, 'XiaoMing'); //只插入部分字段 insert into stu values(null, select id from stu2 where name='xxx'); //插入一组 insert into stu select * from stu2; //将stu2 数据插入stu1中。 create table stu as select * from stu2; //创建stu并插入stu2中数据。 1 2 3 4 52.更新记录:update:修改表中一行或者多行中一个字段或者多个字段的记录。当遇到unqiue约束时候,更新可能会失败。例子:update stu set id=4,score=99.9 where id=5; 13.删除记录:delete例子:delete from stu where id=4; //按条件删除记录 delete from stu; //删除表中所有记录 1 22.数据完整性用于定义和保护表内部和表之间的数据关系。有四种完整性:域完整性、实体完整性、引用完整性、用户自定义完整性。数据完整性是通过约束实现的。约束就是对字段存储值得一种限制,数据库对字段中存储值进行完整性约束强制实施。字段级约束包括:not null、unique、primary key、foreign key、check和collate。1.实体完整性: 主键:primary key:行必须在某种方式上是唯一的。主键必须由带有unique(唯一性)约束的一个或一组字段组成。unique约束是主键的基础。主键提供自增长功能。表默认会创建一个主键(64-bit类型)。 我们也可以自己创建主键,可以定义在多个字段,也不必要是int型。 unique:唯一性约束:保证一个或一组字段的所有值互不相同,如果视图插入一个重复值,将引发非法约束终止操作。2.域完整性:定义中的字段值必须是字段定义范围内的。由两部分组成:类型检查和范围检查。默认值、not null 和 check以及排序。 默认值:如果insert时候没有为该字段指定值,则关键字default为字段设定一个默认值。还接受3种预留定义格式的ANSI/ISO保留字,用于生成时间日期。 current_time: hh:mm:ss current_date: yyyy-mm-dd current_timestamp: yyyy-mm-dd hh:mm:ss 1 2 3 not null:该约束保证该字段不为null。如果给限制not null的字段insert或者update 为null则报错。一般与default一起使用,未赋值的时候使用默认值。 check:测试要插入或者更新的字段值,如果不满足则报错。 例子:create table stu (id integer primary key, name text not null, phone text not null default 'unknown', unique(name, phone),check(length(phone)>7)); 1 外键:确保一个表中关键字从另一个表中引用,且数据在另一个表中实际存在。 例子:create table food (id integer primary key, type_id integer references food_types(id) on delete restrict deferrable initially deferred, name text); delete restrict:阻止这样的删除,如果删除food_types表中id,那么food中id没有父id存在,则阻止删除事务。 deferrable:控制定义的约束立即强制实施还是延迟执行。 1 2 33.存储类SQLite有五个原始数据类型,integer(整数)、real(浮点数)、text(字符串)、blob(二进制)、null。在SQLite中不同存储类的值可以存储在同一个字段中。他们可以排序 null < integer/real < text < blob4.视图即虚拟表,也称派生表,因为他们的内容都是派生自其他表的查询结果。视图虽然看起来像基本表,但是他们不是,基本表是永久的,他们是动态产生的。视图是只读的,无法进行insert、update、delete。创建视图create view name as select id from stu; name:视图名称 1删除视图:drop view name; 1查询视图:创建完视图之后就可以像查询表一样查询视图:select *from name; 15.索引一种用来在某种条件下加速查询的结构。SQLite使用B-tree做索引。索引会增加数据库的大小,索引可以加快查询速度,但是会降低insert、update、和delete的速度。基本语法:CREATE INDEX checkin_f_query on checkin_f; checkin_f_query:索引名。checkin_f索引所在的表名。 1唯一索引:不允许重复的值插入表中。CREATE UNIQUE INDEX checkin_f_query on checkin_f (userid, check_in_time); 索引值是唯一的。 1单例索引:基于一个表上一个列的索引。CREATE INDEX checkin_f_query on checkin_f (userid); 1删除索引:DROP INDEX checkin_f_query; 16.触发器是数据库的回调函数,当具体表发生特定的数据库事件时,会执行对应的SQL语句。触发器是通过名称、行为、表定义的。行为由一系列SQL命令组成,当发生某些特定事件时触发器就会执行这些命令。可以通过关键字before和after来指定是在事发前执行还是事发后执行。事件包括具体在表中执行的delete、update、insert。例子:当 record_f_num > 12000时候,删除checkin_f 表中时间最早的一条记录CREATE TRIGGER checkin_max_12K after update on log WHEN new.key='record_f_num' AND new.value>12000 BEGIN delete from checkin_f where check_in_time in (select check_in_time from checkin_f order by check_in_time limit 1 offset 0); END错误处理:定义事件发生执行前可以使用触发器阻止事件,也可以在发生后使用触发器检查事件。SQL函数raise()函数供触发器使用,该函数允许在触发器内产生错误。函数定于:raise(resolution, err_msg);参数:resolution:冲突解决策略,replace、abort、fail、ignore、rollback err_msg:错误消息7.事务事务定义了一组SQL命令的边界,这组命令或者作为一个整体被全部执行,或者都不执行。事务的范围:事务由三个命令控制:begin、commit、rollback。begin开始一个事务,begin之后的所有操作都可以被取消。commit提交事务开始后所执行的所有操作。rollback回滚begin之后的所有操作。冲突解决:既可以在SQL命令中指定也可以在表和索引中执行。处理约束违法的方法replace:当违反了唯一性约束时,SQL将违反的记录删除,以插入或者修改新的记录替代。当违反not null约束时就使用该字段的默认值来替代null,如果没有默认字段则使用abort的处理方式。ignore:当违反约束时选择忽视,SQL命令继续执行,违反约束的行保持不变,且不报错。fail:当违反约束时,SQLite终止命令,但是不恢复之前已经修改过的记录。abort:当违反约束时,SQLite恢复命令所做的所有改变并终止。是SQLite默认的解决办法。rollback:当违反约束时,执行回滚-终止当前命令和整个事务。当前命令所作的改变和事务中之前所作的改变都被回滚。例子:sqlite> begin; sqlite> insert or replace into table (col_List) values (value_list); sqlite> commit;数据库锁:SQLite采用粗粒度锁,当一个连接要写数据库时,所有其他的连接都被锁住,直到写连接结束它的事务。SQLite有一个加锁表,帮助不同的写数据库能够在最后一刻加锁,以保证最大的并发性。SQLite有五种不同的锁状态:未加锁、共享、预留、未决和排它。数据库在同一时刻只能有一种锁状态。 未加锁:最初的状态,连接却没有访问数据库或者已经begin一个事务时,都是未加锁状态。 共享锁:为了从数据库读数据,连接必现进入共享锁,多个连接可以同时获得并保持共享锁,多个连接可以同一时刻同时从一个数据库读数据。但是如果有共享锁没有释放就不可以写数据。 预留锁:如果想要写数据,必须获取一个预留锁,一个数据库只能有一个预留锁,预留锁可以与共享锁共存,他不会影响其他连接继续获取共享锁。一旦连接获取到预留锁就可以写数据库,但是只写到缓存中,并没有写到磁盘中。 排它锁:当一个连接写完数据想要提交时候,就需要从预留锁提升为排它锁。但是在这之前需要先提升为未决锁,获得未决锁之后其他连接就不可以继续获得共享锁,但是拥有共享锁的仍可以继续工作。此时拥有未决锁的连接等待其他获得共享锁的连接释放共享锁。当其他共享锁都释放完之后,未决锁提升为排它锁,此时就可以对数据库进行修改,然后保存到数据库文件。事务的类型:SQLite有三种不同的事务,他们以不同的锁状态启动事务。begin [deferred | immediate | exclusive] transaction;deferred:直到使用时候才获取锁immediate:在begin执行时候视图获取预留锁,成功则写数据库,失败则返回SQLITE_BUSY错误。exclusive:获取数据库的排它锁。成功就可以对数据库进行任意操作。8.数据库管理控制数据库如何操作附加数据库:SQLite允许使用attach命令将多个数据库附加到当前连接上。当附加上一个数据库时,他的所有内容在当前数据库文件的全局范围内都是可存取的。语法:attach database filename as database_name; filename:数据库文件名。database_name:引用数据库和对象的逻辑名称。数据库配置:SQLite没有配置文件,它所有配置文件都是用编译指示来实现的。连接缓冲区大小:缓存区尺寸大小的编译指示控制一个连接可以在内存中使用多少个数据库页。缓冲区越大,连接在获取排它锁之前所做的事就越多。查看缓冲区大小:pragma cache_size; 设置缓冲区大小:pragma cache_size=10000; 获取数据库信息:pragma database_list; //列出所有附着的数据库pragma index_info; //列出索引内字段的相关信息pragma index_list; //列出表中索引信息pragma table_info; //列出表中所有字段信息写同步:SQLite会在关键时候将所有的变化提交到磁盘以确保事务的持久性。可以通过synchronous编译指示来实现。该编译指示有三种: full:在关键的暂停以确保所有数据都写入磁盘,最安全但是比较慢。 normal:会在绝大多数关键点暂停,没有full频繁。 off:将数据抛给操作系统后继续执行,一旦断电或者崩溃数据库将无法保存到数据。————————————————版权声明:本文为CSDN博主「青湦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_34934140/article/details/121539905
-
我发现同样的程序,同样的sql,在小米等android设备上是可以执行的,但是在鸿蒙2.0上却执行失败,譬如select count() over(),在鸿蒙上就执行失败了,而select count()成功了,难道鸿蒙不支持over()函数的实现?
-
需要实现:12345if not exists(select * from ErrorConfig where Type='RetryWaitSeconds')begin insert into ErrorConfig(Type,Value1) values('RetryWaitSeconds','3')end只能用:123insert into ErrorConfig(Type,Value1)select 'RetryWaitSeconds','3'where not exists(select * from ErrorConfig where Type='RetryWaitSeconds')因为 SQLite 中不支持SP补充:sqlite3中NOT IN 不好用的问题在用sqlite3熟悉SQL的时候遇到了一个百思不得其解的问题,也没有在google上找到答案。虽然最后用“迂回”的方式碰巧解决了这个问题,但暂时不清楚原理是什么,目前精力有限,所以暂时记录下来,有待继续研究。数据库是这样的:1234567891011121314151617181920212223CREATE TABLE book ( id integer primary key, title text, unique(title));CREATE TABLE checkout_item ( member_id integer, book_id integer, movie_id integer, unique(member_id, book_id, movie_id) on conflict replace, unique(book_id), unique(movie_id));CREATE TABLE member ( id integer primary key, name text, unique(name));CREATE TABLE movie ( id integer primary key, title text, unique(title));该数据库包含了4个表:book, movie, member, checkout_item。其中,checkout_item用于保存member对book和movie的借阅记录,属于关系表。问一:哪些member还没有借阅记录?SQL语句(SQL1)如下:1SELECT * FROM member WHERE id NOT IN(SELECT member_id FROM checkout_item);得到了想要的结果。问二:哪些book没有被借出?这看起来与上一个是类似的,于是我理所当然地运行了如下的SQL语句(SQL2):1SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item);可是——运行结果没有找到任何记录! 我看不出SQL2与SQL1这两条语句有什么差别,难道是book表的问题?于是把NOT去掉,运行了如下查询语句:1SELECT * FROM book WHERE id IN(SELECT book_id FROM checkout_item);正确返回了被借出的book,其数量小于book表里的总行数,也就是说确实是有book没有借出的。接着google(此处省略没有营养的字),没找到解决方案。可是,为什么member可以,book就不可以呢?它们之前有什么不同?仔细观察,发现checkout_item里的book_id和movie_id都加了一个unique,而member_id则没有。也许是这个原因?不用id了,换title试试:1234SELECT * FROM book WHERE title NOT IN( SELECT title FROM book WHERE id IN( SELECT book_id FROM checkout_item));确实很迂回,但至少work了。。。问题原因:当NOT碰上NULL事实是,我自己的解决方案只不过是碰巧work,这个问题产生跟unique没有关系。邱俊涛的解释是,“SELECT book_id FROM checkout_item”的结果中含有null值,导致NOT也返回null。当一个member只借了movie而没有借book时,产生的checkout_item中book_id就是空的。解决方案是,在选择checkout_item里的book_id时,把值为null的book_id去掉:1SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item WHERE book_id IS NOT NULL);总结我在解决这个问题的时候方向是不对的,应该像调试程序一样,去检查中间结果。比如,运行如下语句,结果会包含空行:1SELECT book_id FROM checkout_item而运行下列语句,结果不会包含空行:1SELECT member_id FROM checkout_item这才是SQL1与SQL2两条语句执行过程中的差别。根据这个差别去google,更容易找到答案。当然了,没有NULL概念也是我“百思不得其解”的原因。转载自https://www.jb51.net/article/203321.htm
-
1. SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎; 2. 整个数据库存储在一个单个的文件中,数据导入导出备份恢复都是复制文件,维护难度为零; 3. 读取速度快。 4. 最简单的理解是,对比其他数据库,最大区别在于在使用前不需要配置,直接使用即可。 插件导入Studio后,见下图所示,共有4个控件,连接、关闭、执行查询和执行。“执行查询sql语句”控件和“执行sql语句”控件区别在于后者可执行多条语句,可以是增删改查,但没有返回值,需要返回查询的结果则需要使用前者。(1)使用教程见附件“dbsqlite3教程_前部分.mp4”,“dbsqlite3教程_后部分.mp4”;(2)教程中样例见“Template.zip”中“Sqlite3_Template.zip”;(3)sqlite3与excel交互场景可见“Template.zip”中“Sqlite3_Excel_Template.zip”;(4)Sqlite3插件见“ext_dbsqlite3_1_0_0.zip”;(5)Sqlite可视化工具见“DB.Browser.for.SQLite-3.11.0-beta3-win64.zip”,适用于win10/64位,其他系统可在百度自行下载。
-
SQLite 数据类型是一个用来指定任何对象的数据类型的属性。SQLite 中的每一列,每个变量和表达式都有相关的数据类型。您可以在创建表的同时使用这些数据类型。SQLite 使用一个更普遍的动态类型系统。在 SQLite 中,值的数据类型与值本身是相关的,而不是与它的容器相关。SQLite 存储类每个存储在 SQLite 数据库中的值都具有以下存储类之一:存储类描述NULL值是一个 NULL 值。INTEGER值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。REAL值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。TEXT值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。BLOB值是一个 blob 数据,完全根据它的输入存储。SQLite 的存储类稍微比数据类型更普遍。INTEGER 存储类,例如,包含 6 种不同的不同长度的整数数据类型。SQLite Affinity 类型SQLite 支持列上的类型 affinity 概念。任何列仍然可以存储任何类型的数据,但列的首选存储类是它的 affinity。在 SQLite3 数据库中,每个表的列分配为以下类型的 affinity 之一:Affinity描述TEXT该列使用存储类 NULL、TEXT 或 BLOB 存储所有数据。NUMERIC该列可以包含使用所有五个存储类的值。INTEGER与带有 NUMERIC affinity 的列相同,在 CAST 表达式中带有异常。REAL与带有 NUMERIC affinity 的列相似,不同的是,它会强制把整数值转换为浮点表示。NONE带有 affinity NONE 的列,不会优先使用哪个存储类,也不会尝试把数据从一个存储类强制转换为另一个存储类。SQLite Affinity 及类型名称下表列出了当创建 SQLite3 表时可使用的各种数据类型名称,同时也显示了相应的应用 Affinity:数据类型AffinityINTINTEGERTINYINTSMALLINTMEDIUMINTBIGINTUNSIGNED BIG INTINT2INT8INTEGERCHARACTER(20)VARCHAR(255)VARYING CHARACTER(255)NCHAR(55)NATIVE CHARACTER(70)NVARCHAR(100)TEXTCLOBTEXTBLOBno datatype specifiedNONEREALDOUBLEDOUBLE PRECISIONFLOATREALNUMERICDECIMAL(10,5)BOOLEANDATEDATETIMENUMERICBoolean 数据类型SQLite 没有单独的 Boolean 存储类。相反,布尔值被存储为整数 0(false)和 1(true)。Date 与 Time 数据类型SQLite 没有一个单独的用于存储日期和/或时间的存储类,但 SQLite 能够把日期和时间存储为 TEXT、REAL 或 INTEGER 值。存储类 日期格式TEXT格式为 "YYYY-MM-DD HH:MM:SS.SSS" 的日期。REAL从公元前 4714 年 11 月 24 日格林尼治时间的正午开始算起的天数INTEGER从 1970-01-01 00:00:00 UTC 算起的秒数。您可以以任何上述格式来存储日期和时间,并且可以使用内置的日期和时间函数来自由转换不同格式。参考文章:http://www.manongjc.com/sqlite/sqlite_data_types.html
-
Android SQLite,是一款轻量级的关系型数据库。在很多嵌入式设备都用来存储数据。SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了,因而特别适合在移动设备上使用。(内存小就是王道)SQLite数据类型存储类描述NULL值是一个 NULL 值。INTEGER值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。REAL值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。TEXT值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。BLOB值是一个 blob 数据,完全根据它的输入存储。SQLiteDatabase的介绍Android提供了创建和是用SQLite数据库的API。SQLiteDatabase代表一个数据库对象,提供了操作数据库的一些方法。在Android的SDK目录下有sqlite3工具,我们可以利用它创建数据库、创建表和执行一些SQL语句。下面是SQLiteDatabase的常用方法。方法描述openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)打开或创建数据库insert(String table,String nullColumnHack,ContentValues values)插入一条记录delete(String table,String whereClause,String[] whereArgs)删除一条记录query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)查询一条记录update(String table,ContentValues values,String whereClause,String[] whereArgs)修改记录execSQL(String sql)执行一条SQL语句close()关闭数据库打开或创建数据库在Android 中使用SQLiteDatabase的静态方法openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)打开或者创建一个数据库。它会自动去检测是否存在这个数据库,如果存在则打开,不存在则创建一个数据库;创建成功则返回一个SQLiteDatabase对象,否则抛出异常FileNotFoundException。下面是创建名为“stu.db”数据库的代码:openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)参数1 数据库创建的路径参数2 一般设置为null就可以了db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/stu.db",null);创建表创建了一张用户表,属性列为:id(主键并且自动增加)、sname(学生姓名)、snumber(学号)private void createTable(SQLiteDatabase db) { // 创建表SQL语句 String stu_table="CREATE TABLE IF NOT EXISTS usertable(_id integer primary key autoincrement,sname text,snumber text)"; // 执行SQL语句 db.execSQL(stu_table); }参考文章:https://tiimor.cn/Android%E9%BB%84%E9%87%91%E7%AF%87-SQLite%E6%95%B0%E6%8D%AE%E5%BA%93/(非常不错一篇文章满满的细节,建议细细品)
-
sQlite是D. Richard Hipp 用C语言编写的开源嵌入式数据库引擎。它是完全独立的,没有外部依赖性。占用资源非常低,在嵌人式设备中,只需要几百KB的内存。它能够支持Windows, Limux等主流操作系统,可与Tel, PHP和Java等程序语言结合,提供ODBC接口,其处理速度甚至令开源世界著名的数据库管理系统MysQL和PostgreSQL.望尘莫及。solie对50192标准的支持包括索引、限制、触发和查看,支持原子的、一致的、独立的和持久(ACID)的事务。在内部, SoLite由SQL编译器、内核、后端以及附件几个组件组成。 sqlite通过利用虚拟机和虚拟数据库引擎(VDBE) ,使调试、修改和扩展SQLite的内核变得更加方便。所有sql,语句都被编译成易读的,可以在SQLite虚拟机中执行的程序集。现在项目需要使用SOLite数据库,需要将SQLite移植到ARM 2440嵌人式主机中,并续写一个简单的测试程序。现在项目需要使用sqlite数据库 需要将sqlite移植到arm2440嵌入式主机中并编写一个简单的测试程序项目实施步骤:1)下载并编译sqlite2)下载到arm虚拟机并使用sqlite如何下载编译sqlite从http://www.sqlite.org/download.html下载sqlite文件 当前版本是:3.9.2 文件名为:sqlite-autoconf-3090200.tar.gz解压并查看当前目录及install文件# tar zsf sqlite -autoconf-309200.tar,gz#lsaclocal.m4 configure.ac #itmain.sh #Readme#sqlite3ext.hconfig guess depcomp make file.am shell.c sqlite3.hconfig.sub install makefile.in sqlite 3.1 sqlite 3.pc inconfigure install-sh missing sqlite3.c tea创建一个目录build进入主目录在这个目录中将进行交叉编译在build目录中运行sqlite-autoconf-309200中的configure脚本 生成makefile文件 代码如下:../configure--host=ARM-LINUX -- PREFIX =/opt/sqlite-autoconf-309200/build 选项host指定的是用arm交叉编译器进行编译 选项prefix后面的鲤鱼精是编译安装后目标存放的目录可以任意设置#mkdir build #cd mkdir #../configure --houst=arm-linux--prefix=/opt/sqlite-autoconf-309200/build#ls#config.log config.log config.status libtool makefile sqlite3.pc#make #makeinstall#lsbin include libtool sqlite3 sqlite3.pcconfig.log lib makefile sqlite3.lo sqkite3-shell.oconfig.status libsqlite3.la share sqlite3.o sqlite3-sqlite3.o编译和安装完成后 在/root/sqlite-autoconf-309200/bulid 目录中会生成3个目标文件夹 分别是bin include和lib下载到arm虚拟机并使用sqlite 分别将bin下的文件下载到开发板的/user/bin目录中去 lib下的所有文件下载到开发板的/lib目录中即可nclude目录下是sqlite的c语言api的头文件编译时会用到下面示例在arm虚拟机中测试 将root/sqlite-autoconf-309200/build目录中的bin和lib分别复制到/opt/root_qtopia/usr/bin与root_qyopia/lib/目录中#cd /opt/sqlite-autoconf-309200/build#cd bin#cp *.*/opt/root_qtopia/usr/bin#cd..#cd lib#cp *.*/opt/root_qtopia/lib/启动虚拟机 在arm虚拟机终端中运行 sqlite3 tst.db测试运行是否正常#sqlite3 tst.db sqlite version.................sql使用命令行管理数据库 在运行.help会列出常用的命令说明 这里我就不打出来了 也可以在官网中 去查看作者:仙女本仙
-
#define SQLITE_OK 0 /* 成功 | Successful result */ /* 错误码开始 */ #define SQLITE_ERROR 1 /* SQL错误 或 丢失数据库 | SQL error or missing database */ #define SQLITE_INTERNAL 2 /* SQLite 内部逻辑错误 | Internal logic error in SQLite */ #define SQLITE_PERM 3 /* 拒绝访问 | Access permission denied */ #define SQLITE_ABORT 4 /* 回调函数请求取消操作 | Callback routine requested an abort */ #define SQLITE_BUSY 5 /* 数据库文件被锁定 | The database file is locked */ #define SQLITE_LOCKED 6 /* 数据库中的一个表被锁定 | A table in the database is locked */ #define SQLITE_NOMEM 7 /* 某次 malloc() 函数调用失败 | A malloc() failed */ #define SQLITE_READONLY 8 /* 尝试写入一个只读数据库 | Attempt to write a readonly database */ #define SQLITE_INTERRUPT 9 /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */ #define SQLITE_IOERR 10 /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* 数据库磁盘映像不正确 | The database disk image is malformed */ #define SQLITE_NOTFOUND 12 /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */ #define SQLITE_FULL 13 /* 因为数据库满导致插入失败 | Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* 无法打开数据库文件 | Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* 数据库锁定协议错误 | Database lock protocol error */ #define SQLITE_EMPTY 16 /* 数据库为空 | Database is empty */ #define SQLITE_SCHEMA 17 /* 数据结构发生改变 | The database schema changed */ #define SQLITE_TOOBIG 18 /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* 由于约束违例而取消 | Abort due to constraint violation */ #define SQLITE_MISMATCH 20 /* 数据类型不匹配 | Data type mismatch */ #define SQLITE_MISUSE 21 /* 不正确的库使用 | Library used incorrectly */ #define SQLITE_NOLFS 22 /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* 授权失败 | Authorization denied */ #define SQLITE_FORMAT 24 /* 附加数据库格式错误 | Auxiliary database format error */ #define SQLITE_RANGE 25 /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */ #define SQLITE_ROW 100 /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */ /* 错误码结束 */
上滑加载中
推荐直播
-
华为云码道Skill实战与极速交付,智能开发全链路实战2026/07/22 周三 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;姜浩-华为云HCDG核心组成员
直播深度解读华为云码道6月产品新特性,从Skill市场安装专家技能,带你零距离体验从需求,开发,审查,重构全链路闭环的开发过程。从零构建并交付一个完整项目,让您体验从代码提交到服务上线的“极速”之旅。
回顾中 -
聚开发者之力,创具身新未来2026/07/23 周四 15:00-17:00
张豪杰/程文/王军/刘新春/黄钦开 /张晓天
本次华为云具身智能开发平台CloudRobo培训面向具身智能开发者,带您全流程体验机器人本体R2C小时级接入、环境重建与轨迹生成仿真数据生产、PB级数据管理、数据评测、模型训推、强化学习和Benchmark一键评测等功能,并体验业界主流具身模型应用。
回顾中
热门标签