尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
PostgreSQL 查询全部函数信息:从 pg_proc 到综合模板
1. 为什么需要把数据库里的函数全部查出来几个真实场景先讲个实际例子。我接手过一个跑了三年的业务系统里面几十个服务共用一个 PostgreSQL 实例。某天要做数据迁移前的合规盘点DBA 要求把所有自定义函数、触发器和存储过程全部登记造册。我一开始以为直接翻数据库文档就行结果发现文档早过时了实际生产库比文档多出来十多个函数。从那以后我就养成了习惯任何一次变更之前先把函数清单拉出来对齐一遍。你可能会问查函数列表这种事图形化工具里点开树形节点不就有了吗确实有但当你面对的是几百上千个函数、需要批量核对归属模式、需要判断某个函数最近有没有被修改、需要把函数定义一键导出给其他团队评审时依靠 GUI 逐个看根本不现实。更关键的是很多自动化脚本场景——比如发布系统要自动校验新版本 SQL 脚本里的函数是否已存在、数据比对工具要排除函数干扰——都需要在命令行里直接拿到一份结构化、可筛选的函数清单。所以这篇文章就围绕一句话展开在 PostgreSQL 里怎么把全部函数信息查出来尤其是把所有函数名一次性列全并且还能按需带上参数、返回类型、定义语句这些细节。我会从最常用的pg_proc系统表讲到information_schema.routines视图再讲psql下的快捷命令最后给几个我实际用过的综合查询模板。无论你是刚接触 PostgreSQL 的新人还是已经写过不少存储过程的开发者这几套方法都够用。需要提前说明的是文章里所有查询我都基于 PostgreSQL 14/15/16 验证过但pg_proc的结构在 PG 11 之后变化不大大部分查询在较老版本上也能跑通。如果你的库是 Greenplum、PolarDB 这类兼容 PostgreSQL 内核的数据库原理一致个别字段名可能需要微调。2. 三套查询入口的对比pg_proc、information_schema.routines 与 psql 元命令在动手写 SQL 之前先弄清楚 PostgreSQL 提供了哪几条路走到函数信息面前。我最早查函数列表用的是\df后来发现它只是封装了系统查询不方便做复杂过滤这才逐步转向手动写 SQL。三条路各有利弊我列个表说明一下。入口本质优点局限pg_proc系统表PostgreSQL 内部存储函数/过程元数据的核心表信息最全包含函数定义、权限、依赖、并行安全标记等底层字段字段多且杂需要 join 其他表才能拿到模式名、类型名information_schema.routines视图遵循 SQL 标准的视图对外暴露规范化字段符合标准跨数据库迁移时心智负担小字段名友好不含函数体定义部分 PG 特有字段缺失psql的\df系列元命令psql 客户端内置的快捷查询零学习成本几秒钟就能看到结果没法做复杂 join 和自定义过滤输出格式固定我的建议是日常快速查看用\df写脚本或做深度检查时用pg_proc如果公司规范要求 SQL 尽量兼容多种数据库那优先information_schema.routines。但就查全部函数名这个需求来说pg_proc是最终答案。原因很简单函数名存储在pg_proc.proname字段里它是 PostgreSQL 所有函数元数据的源头information_schema只是它的一个标准化投影。2.1 pg_proc 表里有哪些关键字段pg_proc是 PostgreSQL 目录表之一每一行代表一个函数、过程或聚合函数。核心字段大概这些proname函数名字注意这个名字可以重复因为 PostgreSQL 支持函数重载同名不同参的函数是两个独立对象。pronamespace函数所属模式的 OID需要 joinpg_namespace才能拿到模式名。proowner函数属主的 OIDjoinpg_user或pg_authid拿用户名。proargs/proargtypes参数类型信息前者是参数名数组后者是参数类型 OID 数组。prorettype返回类型的 OID。prosrc函数体源码。对于 SQL 语言函数这里直接是函数体文本对于 C 语言函数这里是库函数名。prolang函数实现语言的 OIDjoinpg_language拿到语言名比如sql、plpgsql、c。proacl访问权限列表。prokindPG 11 之后引入的对象类型标记f表示普通函数p表示存储过程a表示聚合函数w表示窗口函数。这个prokind字段非常实用。如果只按函数名去查你会把存储过程、聚合函数、窗口函数也带出来有些场景你可能希望把它们区分开。待会儿我给的综合查询里会专门用到它。2.2 information_schema.routines 视图适合什么场景information_schema.routines是 SQL 标准视图字段名像routine_name、specific_name、routine_type、data_type这种看名字就知道含义。它有个好处是会把重载函数用specific_name区分开因为标准里函数可以重载单靠routine_name不够唯一。但是要注意这个视图不返回函数体也就是你拿不到prosrc对应的内容。所以当标题里说函数信息而不只是函数名时我默认你大概率还想看到函数能不能直接导出定义。这时候information_schema就帮不上忙了得回到pg_proc或使用pg_get_functiondef函数。我平时用information_schema.routines主要场景是写跨数据库兼容的报表或者给非 PostgreSQL 背景的同事看。自己排查问题的话还是pg_proc顺手。3. 一条命令拿到全部函数名最精简的查询和它的边界先上最简单的东西。如果你只要函数名列表不管参数、不管模式就这么查SELECT proname FROM pg_proc;这条语句会把当前数据库里所有函数名列出来包括系统内置函数和用户自定义函数。实际跑一下你会发现结果有几千行——一个全新安装的 PostgreSQL 实例默认系统函数就有两千多个。所以全部函数这个说法一定要想清楚是全部用户函数还是连同系统函数一起。为了把范围收窄到用户函数常规做法是排除pg_catalog和information_schema这两个系统模式下的对象SELECT p.proname FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema);这条查询是我最常用的基础版。如果你在建表时使用了public之外的业务模式也可以改成只看特定模式SELECT p.proname FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname public;但这里有一个非常关键的坑pg_proc里只有函数名没有参数列表而 PostgreSQL 允许同名函数重载。也就是说你查出十个同名update_user光看名字根本不知道哪个是哪个。要区分它们必须把参数类型接上。所以接下来我给真正能用于实际工作的完整版。3.1 同名函数的去重与重载处理PostgreSQL 的函数重载机制和 Java 的方法重载一样只要参数类型列表不同两个函数就能同时存在。例如CREATE FUNCTION calculate(a integer) RETURNS integer ... CREATE FUNCTION calculate(a text) RETURNS integer ...在pg_proc里这两行记录的proname都叫calculate但proargtypes字段的 OID 数组不一样。如果你想精确引用其中一个就得使用pg_get_function_identity_arguments(oid)这个函数把参数签名拼出来。我把这个方法直接写到综合查询里你复制就能用。4. 实际生产可用的综合查询模板函数名、参数、返回类型、模式一次拿全下面这个查询是我现在最常丢给新同事的模板也是标题里函数信息和函数名全部合起来最完整的答案SELECT n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS identity_args, pg_get_function_result(p.oid) AS return_type, CASE p.prokind WHEN f THEN FUNCTION WHEN p THEN PROCEDURE WHEN a THEN AGGREGATE WHEN w THEN WINDOW END AS object_type, l.lanname AS language, pg_get_userbyid(p.proowner) AS owner, p.prosrc AS source_code FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace JOIN pg_language l ON l.oid p.prolang WHERE n.nspname NOT IN (pg_catalog, information_schema) AND p.prokind IN (f, p) ORDER BY n.nspname, p.proname;这个查询我拆开解释一下pg_get_function_identity_arguments(p.oid)返回的是函数的参数签名包含参数名和类型。有了它重载的同名函数就能区分开。pg_get_function_result(p.oid)返回返回类型的可读文本避免你自己去 joinpg_type做类型名解析。p.prokind区分函数、过程、聚合、窗口四类。如果你只想要普通函数和存储过程IN (f,p)就够了。p.prosrc是函数体源码。对于plpgsql和sql语言函数这里就是完整函数定义体对于没权限查看的函数这里可能是空或者报权限错误。执行结果类似下面这样schema_namefunction_nameidentity_argsreturn_typeobject_typelanguageownersource_codepublicadd_audit_logevent text, user_id integertriggerFUNCTIONplpgsqlapp_userBEGIN ... ENDpublicupdate_useruser_id integer, name textvoidFUNCTIONplpgsqlapp_userBEGIN ... END这个结果已经能直接拿去做函数清单登记了。但标题里特别强调函数名全部我觉得有必要再展开讲讲全部背后的几个过滤维度和坑。4.1 如何连存储过程、聚合函数、窗口函数一起查出来刚才的查询里我用了p.prokind IN (f, p)这是默认推荐。但如果你需要全部可以直接去掉这行过滤或者改成四种类型全要SELECT n.nspname AS schema_name, p.proname AS function_name, CASE p.prokind WHEN f THEN FUNCTION WHEN p THEN PROCEDURE WHEN a THEN AGGREGATE WHEN w THEN WINDOW END AS object_type, pg_get_function_identity_arguments(p.oid) AS identity_args FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema) ORDER BY object_type, n.nspname, p.proname;这里有个细节需要留意存储过程是 PG 11 才引入的概念语法上它用CALL调用而不是SELECT而且它允许没有返回值。如果你们的团队有人把存储过程和函数混着叫那这份全量清单就能帮你快速厘清哪些是真正的procedure哪些是普通function。至于聚合函数和窗口函数日常在pg_proc里也会出现。比如你自定义过一个聚合函数my_agg它同样会出现在上述结果里。如果你的目的是盘点业务自定义逻辑建议保留下a和w如果只是发布 SQL 脚本前核对函数是否存在只查f就够了减少噪音。4.2 参数里的 IN、OUT、INOUT 和默认值怎么体现pg_get_function_identity_arguments返回的参数串不包含默认值也不包含参数的IN/OUT/INOUT模式标记或者只在特定情况下部分包含。如果你想要那种可以复制到CREATE FUNCTION语句里直接重建的完整签名得换一个函数SELECT p.oid, pg_get_functiondef(p.oid) AS full_definition FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname public AND p.proname update_user;pg_get_functiondef返回的是一个完整的CREATE OR REPLACE FUNCTION ...语句包含参数默认值、RETURNS子句、LANGUAGE、SECURITY属性等所有内容。这是你把函数定义迁移到另一个库时最省事的方案。但是注意pg_get_functiondef的性能比单纯查pg_proc字段慢不少。如果你要导出几百个函数的完整定义建议一条一条调用并且加上合适的过滤条件不要在一个查询里对整表循环调用。否则几万个系统函数会拖死你的会话。4.3 只查自己关注模式的函数写法实际项目里函数通常分布在多个 schema 下。比如业务函数在public报表函数在reporting定时任务相关在jobs。这种情况下我习惯用动态构造模式列表的方式SELECT n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS identity_args FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname IN (public, reporting, jobs) ORDER BY n.nspname, p.proname;如果你连当前库里有哪些 schema 都不确定先跑这条SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE pg_% ORDER BY 1;5. 特殊函数类型的识别与过滤触发器函数、窗口函数、聚合函数很多人在查函数列表的时候会漏掉一类重要对象——触发器函数。触发器函数本质上就是普通函数只是它的返回类型是trigger并且定义里通常有RETURNS trigger和CREATE TRIGGER配合。如果你只按函数名去搜很容易把它当作普通业务函数忽略掉但在数据审计、操作日志这类场景里触发器函数恰恰是关键。想单独筛选触发器函数可以这样查SELECT n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS identity_args FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace JOIN pg_type t ON t.oid p.prorettype WHERE n.nspname NOT IN (pg_catalog, information_schema) AND t.typname trigger;原理是通过返回类型的类型名是否为trigger来判断。如果哪天你想找所有返回SETOF record的函数也可以把typname换成record或SETOF相关的类型来做变体。窗口函数和聚合函数的过滤相对简单。如果你定义过自定义聚合prokind a就能看见。窗口函数在 PG 里大部分是内置的比如row_number()、rank()等它们都住在pg_catalog已经被我前面的NOT IN排除了。自建窗口函数的场景很少如果真要查把prokind改成w即可。6. 函数依赖关系查询哪些表被哪些函数引用函数列表只是第一步真正做上线评估时还得知道一个函数依赖了哪些表、哪些字段。PostgreSQL 的系统目录里有pg_depend它记录了对象之间的依赖关系。函数对表的依赖分为两种动态 SQL在函数体内拼接表名和静态引用函数体直接使用SELECT * FROM some_table。静态依赖其实不需要逐行解析 SQLPostgreSQL 在创建函数时会记录依赖关系可以通过查询pg_depend间接定位。比如查某个函数依赖了哪些表SELECT dependent_ns.nspname AS dependent_schema, dependent_class.relname AS dependent_function, referenced_ns.nspname AS referenced_schema, referenced_class.relname AS referenced_table FROM pg_depend d JOIN pg_rewrite r ON r.oid d.objid JOIN pg_class dependent_class ON dependent_class.oid r.ev_class JOIN pg_namespace dependent_ns ON dependent_ns.oid dependent_class.relnamespace JOIN pg_class referenced_class ON referenced_class.oid d.refobjid JOIN pg_namespace referenced_ns ON referenced_ns.oid referenced_class.relnamespace JOIN pg_proc p ON p.oid d.refobjid OR p.oid d.objid WHERE dependent_class.relkind v AND referenced_class.relkind r AND dependent_ns.nspname NOT IN (pg_catalog, information_schema);这个查询稍微绕因为 PostgreSQL 对视图和函数的依赖是通过规则系统记录的。我更常用的方法是直接查pg_proc.prosrc里是否包含某个表名字符串虽然不严谨但在快速定位时非常有效SELECT n.nspname AS schema_name, p.proname AS function_name FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema) AND p.prosrc ILIKE %orders%;这条查询的本质就是文本搜索。它的局限在于动态 SQL 中拼接的表名、通过视图间接依赖的表它都看不见但胜在快和直观。真要精确分析依赖建议配合plpgsql_check这类插件做静态分析或者直接在测试环境里模拟执行。7. 权限与可见性为什么有些函数查到了却看不到源码使用超级用户查询时pg_proc.prosrc基本都能直接看到函数体。但如果你用普通业务账号执行同样的查询很可能会发现prosrc字段是空的或者干脆在函数列表里就看不到某些函数。这里涉及 PostgreSQL 的元数据可见性规则。简单来说普通用户对pg_proc表的查询系统会过滤掉他没有权限执行的函数。也就是说函数列表本身也会因为当前账号权限不同而变化。这是一个很多人容易忽略的点你用自己账号查出来的全部函数未必真的是全量。有一个标准的视图专门用来规避这个问题pg_catalog.pg_proc是底层表但实际查询时 PostgreSQL 会应用pg_function_is_visible等可见性判断。如果你需要绕过权限获取系统层面完全真实的函数列表可以查询pg_catalog.pg_proc并使用超级用户身份执行。但注意这是 DBA 级别的操作普通业务账号不应该也不需要这么做。实际项目中我的建议是用只读账号做函数盘点时先把权限核查清楚否则可能造成漏项。比如某公司有个合规任务要求盘点所有自定义函数结果执行查询的账号只能看到public模式下的部分函数另外几个业务模式下的函数完全没出现在结果里。最后换成具备pg_read_all_data权限的账号后多出来三十多个函数。如果你想在 PostgreSQL 15 中给只读账号开权限可以使用预定义的只读角色GRANT pg_read_all_data TO report_user;这样该账号就能看到几乎所有元数据包括函数体源码。注意这个权限相当大生产环境要谨慎评估。8. 函数体源码的获取可能踩到的几个版本差异不同 PostgreSQL 版本里pg_proc.prosrc的行为略有差异。在 PG 14 之前prosrc基本就是函数体的原文不管是sql语言还是plpgsql语言都如此。PG 14 之后对于sql语言的函数系统做了内联处理prosrc仍然保存原始定义文本但如果你用pg_get_functiondef去拿时可能会看到格式化后的完整定义而不是你最初写的那个文本。这个差异会带来一个小坑如果你把prosrc的内容直接当作函数最终定义去对比版本或者做逐字比对可能会发现明明源代码没改动但查询结果里的文本和源码仓库里的文本不一致。原因是 PostgreSQL 在存储时可能对引号、空格做了标准化处理。我实际遇到过一次同事写脚本用prosrc做函数内容 diff结果发现同一个函数在不同环境里查出来的prosrc字符串不一样一度以为是环境配置有差异折腾了半天才发现是函数创建时用了不同的缩进风格而 PostgreSQL 对 SQL 标准函数做了规范化。所以如果你要做函数级版本比对建议用pg_get_functiondef(p.oid)的输出作为基准而不是直接比prosrc原文。9. 完整导出函数定义一条命令备份所有自定义函数前面所有查询都是在数据库内交互式执行的。如果你想把所有自定义函数一次性导出成 SQL 文件其实还有一个不用写 SQL 的官方工具——pg_dump。pg_dump --schemapublic --functionpublic --filefunctions.sql your_database这句话的意思是只导出public模式下的函数以及过程写入functions.sql。如果函数在多个模式可以用多个--schema参数。pg_dump导出的函数定义包含完整的CREATE FUNCTION语句并且会自动处理依赖顺序。对于函数数量多、依赖复杂的库这比手动拼 SQL 可靠得多。不过pg_dump是物理备份思维导出的内容里会包含SET search_path等会话设置不能直接拿到别的库里执行。如果你需要的是干净的建函数脚本可以加上--clean和--if-exists参数让整个文件变成先删后建的幂等脚本pg_dump --schemapublic --functionpublic --clean --if-exists --filefunctions.sql your_database但这也意味着执行时会先DROP FUNCTION IF EXISTS如果你在目标库中已有依赖这些函数的对象执行前需要确认不会误删。10. 函数名列表与对象标识符的唯一性OID 比名字更可靠在 PostgreSQL 里函数的唯一标识其实不是函数名而是函数 OID。重载函数让函数名 参数类型才能唯一确定一个函数。所以在所有需要精确引用函数的自动化脚本中我强烈建议使用 OID 作为主键去关联其他系统表而不是用名字去匹配。如果你想把函数名列表和 OID 一起拿出来在综合查询里多加一列即可SELECT p.oid, n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS identity_args FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema) ORDER BY n.nspname, p.proname;有了 OID 之后你再去做权限管理、依赖分析、审计追踪都会方便很多。比如查某个函数上的GRANT权限SELECT grantee, privilege_type FROM information_schema.routine_privileges WHERE routine_name update_user AND specific_schema public;或者更底层一点直接看pg_proc.proacl字段里的 ACL 数组。但这些都属于延伸话题这篇文章先把函数名下钻到位。11. 一个完整的函数盘点实战场景从查询到登记表为了让你直观看到这套方法怎么组合使用我描述一个完整的场景。假设某公司有业务库appdb里面有public、reporting、jobs三个模式。DBA 要求出一份函数清单内容包括函数名、完整签名区分重载、返回类型、类型函数/过程、所属模式、函数语言、定义体并且要求删除系统函数。还要把触发器函数单独标记出来。我的处理步骤是这样的第一步确认当前库信息SELECT current_database(), version();第二步按模式统计函数数量SELECT n.nspname AS schema_name, COUNT(*) AS function_count FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema) GROUP BY n.nspname ORDER BY n.nspname;第三步导出全部函数的完整信息到 CSV 文件。在 psql 里执行\copy ( SELECT n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS identity_args, pg_get_function_result(p.oid) AS return_type, CASE p.prokind WHEN f THEN FUNCTION WHEN p THEN PROCEDURE WHEN a THEN AGGREGATE WHEN w THEN WINDOW END AS object_type, l.lanname AS language, pg_get_userbyid(p.proowner) AS owner, p.prosrc AS source_code, EXISTS ( SELECT 1 FROM pg_type t WHERE t.oid p.prorettype AND t.typname trigger ) AS is_trigger_function FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace JOIN pg_language l ON l.oid p.prolang WHERE n.nspname NOT IN (pg_catalog, information_schema) ORDER BY n.nspname, p.proname ) TO /tmp/function_inventory.csv WITH (FORMAT CSV, HEADER true, DELIMITER ,);\copy与COPY的区别在于前者是客户端本地文件后者写在服务端目录下。导出到本地再用 Excel/其他工具打开登记起来就很顺手。第四步把结果里is_trigger_function为true的行单独摘出来交给下游团队核对这些触发器函数对应的触发事件是否与审计要求一致。整个流程下来不到十分钟但如果是手动在 GUI 里逐个点开函数看属性一两百个函数至少要折腾一下午。这也是我为什么坚持用系统查询做函数盘点。12. 关于 psql 元命令的几个实用变体我前面强调的是用 SQL 手动查但日常快速看的话psql元命令仍然是最方便的。除了最基础的\df还有这些变体值得记-- 只看 public 模式下的函数 \df public.* -- 模糊匹配名字里含 user 的函数 \df *user* -- 显示函数签名和返回类型带更多细节 \df public.update_user注意\df会额外显示函数的很多属性包括是否泄漏、并行安全、成本估算值等。如果你想快速确认某个函数的返回值类型、稳定性标记\df是零成本方案。不过元命令的输出格式固定不好做自定义过滤。比如你想找所有返回trigger的函数元命令就做不到了还是要回 SQL。所以我的习惯是临时查看用\df批量处理、深度检查用 SQL两者结合效率最高。13. 我的几条实操经验与最后的提醒最后分享几个我踩过的坑和总结出的经验。第一永远不要在生产库上执行无过滤的SELECT * FROM pg_proc更不要直接对全表调用pg_get_functiondef。这个表动辄几万行一旦循环调用格式化函数会造成不必要的 IO 和 CPU 开销。一定要先用条件把范围缩到业务模式。第二函数名大小写的问题。PostgreSQL 对未加引号的函数名默认折叠成小写。如果你创建函数时用了大写字母并加了双引号比如CREATE FUNCTION CalculateUser()那么查询时proname会保留大写。用ILIKE做模糊匹配时要注意大小写敏感性否则可能漏查。第三关于prokind的版本兼容。如果你的数据库还在 PG 10 或更早版本pg_proc表没有prokind字段只有proisagg和proiswindow两个布尔字段来标识聚合和窗口函数。PG 11 引入prokind后proisagg变成了prokinda的冗余表达。老库迁移时你写的查询里如果用到prokind需要先确认版本。第四函数定义里的安全缺陷排查。盘点函数时除了看名字和参数至少要关注prosecdef这个字段。它影响函数以调用者还是定义者身份执行。如果发现某个被高频调用的函数设置了SECURITY DEFINER且属主是超级用户那就要额外小心了。这算是我在做函数盘点时额外养成的习惯——先把安全相关属性过一遍再谈后续改造。SELECT n.nspname AS schema_name, p.proname AS function_name, p.prosecdef AS security_definer FROM pg_proc p JOIN pg_namespace n ON n.oid p.pronamespace WHERE n.nspname NOT IN (pg_catalog, information_schema) AND p.prosecdef true;第五如果函数体特别大prosrc字段会被截断吗实际上prosrc是一个text类型字段能存很大内容一般不会因为函数体长度而出问题。但如果你的函数体是通过pg_dump导出的某些旧版本可能在导出时遇到行宽问题。真遇到这种极端情况用pg_get_functiondef也能拿到完整定义相信工具而不是手工拼接。这些经验不一定每条都能立刻用上但在你真正被函数列表折腾到焦头烂额的时候能帮你少走很多弯路。数据库元数据查询这件事看起来就是几条 SQL 的事但组合起来能解决的问题远超预期。
RELATED

相关推荐

汽车推荐分析系统全链路实现:爬虫、线性回归与Flask可视化

汽车推荐分析系统全链路实现:爬虫、线性回归与Flask可视化

本科阶段的计算机毕业设计里,“汽车推荐分析系统”几乎是长盛不衰的经典选题。但很多同学做出来的版本,往往停留在“爬了几百条数据 画两张图表 套一个线性回归模型”的层面,答辩时最怕老师追问两类问题:一是“你这些数据怎么来…

📅 2026/10/21 8:06:10
平衡膳食指南文档解读:五大类食物与三大营养素供能比落地执行

平衡膳食指南文档解读:五大类食物与三大营养素供能比落地执行

简介:这是一份面向普通大众、营养学习者及健康管理从业者的科普文档,围绕平衡膳食的内涵、重要性与现代实践展开,帮助读者理解如何通过合理搭配食物满足人体近50种营养素的全面需求。文档共1个doc文件,压缩包约21KB,内…

📅 2026/10/21 8:06:10
PL/0编译器添加运算符:词法、语法到P-code虚拟机的完整改动指南

PL/0编译器添加运算符:词法、语法到P-code虚拟机的完整改动指南

简介:编译原理课程设计资料,面向计算机专业本科生,围绕PL/0编译器的修改扩充展开,重点集中在运算符扩展和循环语句实现。内容包含基本要求与选做内容:基本部分完成、-赋值运算以及Pascal FOR语句的TO/DOWNTO两种形式&a…

📅 2026/10/21 8:06:10
MORE NEWS

更多资讯

📰

agent-skills:智能体能力操作系统的架构设计与工程实践

1. 项目概述:这不是一个“技能库”,而是一套可插拔的智能体能力操作系统“agent-skills”这个名称乍看像某个开源仓库的简单命名,但如果你在最近半年深度参与过智能体(Agent)开发实践,就会立刻意识到——它…

📰

LiteLLM:大模型多厂商统一调用的协议翻译器

1. 从“调用大模型像调用API”说起:为什么LiteLLM突然成了团队协作的隐形枢纽我第一次在某跨平台系统的需求评审会上听到“我们统一走LiteLLM层”这句话时,下意识翻了下手机——不是查文档,是确认会议纪要里有没有写错名字。毕竟那会儿&#…

📰

PHP WebSocket实时聊天室实战:从长连接原理到生产部署

聊到“PHP 实时聊天室源码 WebSocket”这个标题,我估计不少人脑子里第一时间冒出来的问题是:PHP 不是处理请求就退出吗?它怎么做长连接?怎么实时推消息?这问题我当年也问过自己。先说结论:PHP 完全可以做 …

📰

房价预测数据预处理实战:缺失值、偏态与编码全解析

做这个比赛的绝大多数人,都会在提交完第一版预测之后陷入同样的困惑:模型换了三四个,调参调得快吐了,分数却始终卡在某个位置不动。很少有人意识到,问题往往不在模型,而在数据预处理。房价预测这类结构化比…

📰

agent-skills:面向智能体的可插拔能力契约设计

1. 项目概述:一个被严重低估的“技能容器”概念“agent-skills”这个词组最近在技术社区和开发者讨论中频繁浮现,但它既不是某个具体开源库的官方命名,也不是某家大厂刚发布的API产品名——它本质上是一种面向智能体(Agent&#x…

📰

DeepSeekAPI智能用例生成实战:自动化测试完整方案

简介:面向软件测试工程师与自动化测试开发者的23页PDF文档,系统讲解如何借助DeepSeek API构建智能用例生成方案。文档从自动化测试框架的定义与常见类型讲起,依次介绍DeepSeek API的基本概念、技术特点、应用场景和密钥获取方式,然…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬