ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Oracle 第十二讲:存储过程 procedure 从创建到调用的完整实践(TaoToken 统一 Key 通道)

Oracle 第十二讲:存储过程 procedure 从创建到调用的完整实践(TaoToken 统一 Key 通道) 1. Oracle 存储过程 procedure 从零上手它到底解决什么问题如果你写过几次 PL/SQL 匿名块大概率会有个疑问每次都要把整段逻辑重新粘贴一遍改一个参数就得全量替换这活儿没法干。存储过程 procedure 就是来解决这个问题的——它本质上是带名字、带参数、存在数据库里的 PL/SQL 程序块创建一次之后谁都能按名字调用。先把它和几个容易混的概念摆清楚。匿名块declare...begin...end;没有名字执行完就没了函数 function 必须有返回值通常用在 SQL 表达式里比如select sal_tax(sal) from emp触发器 trigger 是事件驱动的insert/update/delete 时自动跑你没法手动调。而 procedure 介于中间有名字、可传参、可被exec或begin...end调用、可以没有返回值也可以靠 OUT 参数往外带值。它适合谁数据库初学者拿它练 PL/SQL 语法结构最合适因为参数模式、异常处理、事务控制这些核心概念在 procedure 里全都能练到后端开发者则用它把批量数据处理、定时任务逻辑下沉到数据库层减少应用和数据库之间的往返。这篇我会带你走完整条链路先建一张练习表然后写一个带 IN/OUT/IN OUT 三种参数模式的存储过程再补上异常处理最后用 SQL*Plus 调用并核对结果。同时我会说明怎么用 TaoToken 的统一 Key 通道管理你手头多个 AI 编码工具的接入避免每换一个工具就重新配一遍密钥。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 后面配置章节会给出具体路径。先明确一个前提下面所有脚本都在 Oracle 11g 及以上版本验证过SQL*Plus 和 SQL Developer 都能跑。如果你用的是 Oracle 12c 之后的版本CREATE OR REPLACE PROCEDURE语法完全一致不用担心兼容性。建练习表这一步别跳过很多人卡在存储过程写完了但没数据可测。执行下面这段-- 建一张员工练习表 CREATE TABLE emp_test ( empno NUMBER(4) PRIMARY KEY, ename VARCHAR2(20), sal NUMBER(7,2), deptno NUMBER(2) ); -- 插入几条测试数据 INSERT INTO emp_test VALUES (1001, SMITH, 800, 20); INSERT INTO emp_test VALUES (1002, ALLEN, 1600, 30); INSERT INTO emp_test VALUES (1003, WARD, 1250, 30); INSERT INTO emp_test VALUES (1004, JONES, 2975, 20); COMMIT;跑完SELECT * FROM emp_test;应该能看到 4 行。这张表后面所有例子都用它字段名和经典 emp 表保持一致方便你对照记忆。这里插一句关于工具链的事。写存储过程时你可能会同时开着 SQL Developer、VS Code 里的 AI 补全插件、还有命令行 SQL*Plus。每个工具都要配数据库连接和 API Key管理起来很碎。TaoToken 的思路是给你一个统一的 Key 和 API 通道多个工具共用同一套凭证换工具时不用重新申请。具体怎么配放到第 3 节讲先把存储过程本身跑通。2. 创建第一个 procedure参数模式 IN/OUT/IN OUT 全拆解存储过程的核心难点不在语法而在参数模式。很多人第一次写OUT参数时会懵为什么调用完变量还是空的为什么IN OUT既能进又能出这一节把三种模式逐个拆开每个都配可复制的脚本。先看最基本的语法骨架CREATE OR REPLACE PROCEDURE 过程名 ( 参数名1 [IN | OUT | IN OUT] 数据类型, 参数名2 [IN | OUT | IN OUT] 数据类型 ) IS -- 局部变量声明 BEGIN -- 逻辑主体 EXCEPTION -- 异常处理 END 过程名; /注意末尾那个单独的/在 SQL*Plus 里它表示执行刚才输入的这段 PL/SQL少了它存储过程不会真正创建。这是初学者最常踩的坑之一。IN 参数是默认模式只进不出过程内部不能给它赋值。写一个按部门涨薪的过程CREATE OR REPLACE PROCEDURE raise_salary ( p_deptno IN NUMBER, p_pct IN NUMBER ) IS v_count NUMBER; BEGIN UPDATE emp_test SET sal sal * (1 p_pct / 100) WHERE deptno p_deptno; v_count : SQL%ROWCOUNT; DBMS_OUTPUT.PUT_LINE(受影响行数: || v_count); COMMIT; END raise_salary; /SQL%ROWCOUNT是隐式游标属性拿最近一条 DML 影响的行数。这里顺便回应一下你可能会遇到的游标属性%ISOPEN、%NOTFOUND、%FOUND、%ROWCOUNT这四个在显式游标里用得多而SQL%ROWCOUNT这种隐式游标写法在存储过程里更常见。FOR 循环游标会自动开、自动关不用手动OPEN/CLOSE这点记住就行。OUT 参数用来往外带值过程内部必须给它赋值。写一个查询某部门平均工资的过程CREATE OR REPLACE PROCEDURE get_avg_sal ( p_deptno IN NUMBER, p_avg OUT NUMBER ) IS BEGIN SELECT AVG(sal) INTO p_avg FROM emp_test WHERE deptno p_deptno; EXCEPTION WHEN NO_DATA_FOUND THEN p_avg : 0; DBMS_OUTPUT.PUT_LINE(该部门没有员工); END get_avg_sal; /这里SELECT ... INTO如果查不到行会抛NO_DATA_FOUND所以必须接异常处理否则过程直接报错中断。IN OUT 参数既能读又能写典型场景是传入一个值、加工后再传回。比如给工资设上下限CREATE OR REPLACE PROCEDURE clamp_salary ( p_sal IN OUT NUMBER, p_min IN NUMBER, p_max IN NUMBER ) IS BEGIN IF p_sal p_min THEN p_sal : p_min; ELSIF p_sal p_max THEN p_sal : p_max; END IF; END clamp_salary; /三种模式对照看模式能否读能否写调用时传值典型用途IN是否常量或变量输入条件OUT否是必须是变量返回结果IN OUT是是必须是变量加工后回传有个细节要注意OUT 和 IN OUT 调用时传的必须是变量不能传字面量。你写get_avg_sal(20, 0)会直接报错因为0不是变量没法接收返回值。异常处理部分除了NO_DATA_FOUND常用的还有TOO_MANY_ROWSSELECT INTO返回多行、ZERO_DIVIDE除零、OTHERS兜底。写一个带完整异常分支的例子CREATE OR REPLACE PROCEDURE safe_div ( p_a IN NUMBER, p_b IN NUMBER, p_res OUT NUMBER ) IS BEGIN p_res : p_a / p_b; EXCEPTION WHEN ZERO_DIVIDE THEN p_res : NULL; DBMS_OUTPUT.PUT_LINE(除数不能为 0); WHEN OTHERS THEN p_res : NULL; DBMS_OUTPUT.PUT_LINE(未知错误: || SQLERRM); END safe_div; /SQLERRM返回当前错误信息SQLCODE返回错误码排障时很有用。WHEN OTHERS一定放最后因为它会捕获所有异常。3. 可复制配置TaoToken 统一 Key 通道与工具接入存储过程写多了你会自然想借助 AI 工具来补全、解释、排错。问题在于工具一多密钥管理就乱SQL Developer 插件一套、VS Code 插件一套、命令行工具又一套。TaoToken 提供统一 Key 和 API 通道多个工具共用同一份凭证换工具时只改 Base URL 和 Key 就行。先说清楚它是什么TaoToken 是一个统一的大模型 API 接入通道你申请一个 Key就能在支持自定义 Base URL 的工具里调用多种模型。适合谁适合同时用多个 AI 编码工具、又不想每个都单独配密钥的开发者。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。下面给出三件套配置Base URL、Key、Model ID 一个都不能少。以 Claude Code 的 settings 为例配置文件路径是~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: 你的_TaoToken_Key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }如果你用的是 Cline 这类 VS Code 插件配置走 MCP 或 provider 设置同样是三件套{ provider: anthropic, baseUrl: https://taotoken.net/api, apiKey: 你的_TaoToken_Key, model: claude-sonnet-4-20250514 }Codex 用户走~/.codex/auth.json结构类似{ base_url: https://taotoken.net/api, api_key: 你的_TaoToken_Key, model: claude-sonnet-4-20250514 }Key 从哪来进控制台创建路径是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建后在 API Keys 页面复制页面地址 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。注意 Key 只在创建时完整显示一次复制后妥善保存。配置完怎么验证最直接的方式是用模型对话页面发一条测试消息地址 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 能正常返回就说明 Key 和通道没问题。如果你打算长期用 AI 辅助写存储过程、做代码审查可以考虑 Coding Plan路径 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有各工具的详细配置说明。Claude Code 用户还可以参考 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。这里提醒一句配置里的 Base URL 一定要带/api后缀写成https://taotoken.net会 404。这是最常见的配置错误第 5 节会专门讲。4. 调用验证SQL*Plus 执行与结果核对清单存储过程创建完SQL*Plus里会显示Procedure created.。如果显示带警告的Procedure created with compilation errors.说明有语法错误用SHOW ERRORS看详情。调用方式有两种。第一种是EXEC其实是EXECUTE的缩写-- 调用 IN 参数过程 EXEC raise_salary(30, 10); -- 调用 OUT 参数过程需要先声明变量 VARIABLE v_avg NUMBER; EXEC get_avg_sal(30, :v_avg); PRINT v_avg;注意 OUT 参数在 SQLPlus 里要用绑定变量:v_avg前面加冒号。VARIABLE声明的是 SQLPlus 绑定变量和 PL/SQL 里的局部变量不是一回事。第二种是放在BEGIN...END块里调用这种方式更灵活能直接用 PL/SQL 变量SET SERVEROUTPUT ON; DECLARE v_avg NUMBER; v_sal NUMBER : 500; BEGIN -- 调用 OUT 参数过程 get_avg_sal(30, v_avg); DBMS_OUTPUT.PUT_LINE(部门 30 平均工资: || v_avg); -- 调用 IN OUT 参数过程 clamp_salary(v_sal, 800, 2000); DBMS_OUTPUT.PUT_LINE(调整后工资: || v_sal); END; /SET SERVEROUTPUT ON必须开否则DBMS_OUTPUT.PUT_LINE的输出你看不到。这是初学者第二大坑。执行结果核对清单逐条对第一raise_salary(30, 10)执行后部门 30 的工资应该涨 10%。调用前 ALLEN 是 1600、WARD 是 1250调用后应该是 1760 和 1375。用SELECT empno, ename, sal FROM emp_test WHERE deptno 30;核对。第二get_avg_sal(30, v_avg)应该返回部门 30 的平均工资。如果涨薪后调用平均值是 (17601375)/2 1567.5。第三clamp_salary传入 500下限 800应该返回 800传入 3000上限 2000应该返回 2000。第四异常分支测试safe_div(10, 0, v_res)应该输出除数不能为 0且v_res为 NULL。如果结果对不上先检查有没有COMMIT。raise_salary里我写了COMMIT如果你漏了换个会话查数据就看不到变化。存储过程里的事务控制要谨慎生产环境通常由调用方决定何时提交练习阶段直接COMMIT没问题。再补一个查看存储过程源码的方法排障时常用SELECT text FROM user_source WHERE name RAISE_SALARY ORDER BY line;user_source存的是当前用户下的所有 PL/SQL 源码name要大写。想看过程状态用SELECT object_name, status FROM user_objects WHERE object_type PROCEDURE;status是VALID才算可用。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节把配置和调用过程中最容易撞上的几类报错集中处理。前半段是 TaoToken 接入相关后半段是存储过程本身。401 Unauthorized。这个基本是 Key 的问题。三种可能Key 复制时带了空格或换行Key 已过期或被删除配置里字段名写错比如把ANTHROPIC_AUTH_TOKEN写成了ANTHROPIC_API_KEY。排查方法回控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 重新复制一次 Key粘贴时注意首尾不要有空白字符。如果还不行去模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 用同一个 Key 发条消息能通说明 Key 没问题问题在工具配置。local proxy failed。这个报错通常出现在工具尝试走本地代理但代理没起来的时候。检查你的工具配置里有没有多余的 proxy 设置把HTTP_PROXY、HTTPS_PROXY这类环境变量清掉再试。TaoToken 的 API 端点直接访问即可不需要额外代理层。reading choices 相关报错。这类错误一般出现在响应解析阶段常见原因是 Base URL 写错导致返回的不是预期格式。重点检查 Base URL 是不是https://taotoken.net/api少写/api或者多写斜杠都会出问题。另外确认 Model ID 拼写正确写错模型名有时不会立刻报错而是在解析响应时才暴露。OAuth 相关报错。如果你用的是 Claude Code它默认可能走 OAuth 登录流程。用 TaoToken 的 Key 通道时要确保配置里用的是ANTHROPIC_AUTH_TOKEN而不是走 OAuth。如果工具提示需要登录检查 settings.json 里的 env 段是否生效有时候是配置文件路径放错了Claude Code 读的是~/.claude/settings.json不是项目根目录。存储过程这边的报错ORA-06550 / PLS-00103。语法错误多半是END后面漏了过程名或者IS和AS混用。用SHOW ERRORS PROCEDURE 过程名看具体行号。ORA-01403: no data found。SELECT INTO没查到数据。加NO_DATA_FOUND异常处理或者确认查询条件。ORA-01422: exact fetch returns more than requested number of rows。SELECT INTO返回多行。要么加WHERE收窄条件要么改用游标循环。ORA-06502: numeric or value error。类型不匹配或长度超限常见于VARCHAR2变量接收了超长字符串。Procedure created with compilation errors。创建时报的用SHOW ERRORS定位。注意 SQL*Plus 里SHOW ERRORS默认显示最近创建的对象如果刚创建了别的对象要指定SHOW ERRORS PROCEDURE 过程名。6. 把存储过程接入你的 AI 编码工作流存储过程写顺手之后下一步是让它和你的 AI 工具链配合起来。比如你写了一个复杂的批量处理过程想让 AI 帮你审查有没有性能问题或者遇到一个ORA-报错想让 AI 解释原因。这些场景都需要工具能稳定调用模型。TaoToken 在这里的价值是统一入口。你不需要为每个工具单独申请密钥一个 Key 走通所有支持自定义 Base URL 的工具。配置三件套记住Base URL 是https://taotoken.net/apiKey 从控制台创建Model ID 按工具要求填。三个都对了接入就通了。如果你主要做数据库开发和后端编码长期需要 AI 辅助Coding Plan 会比按次调用更划算路径在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入过程中遇到配置问题先查文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 大部分常见错误里面都有说明。回到存储过程本身给你一个练习建议把这篇里的raise_salary改造成带异常处理的版本加上部门不存在时的提示再写一个用游标循环遍历所有部门、逐个调用get_avg_sal的过程。这两个练习做完参数模式和异常处理基本就吃透了。游标那块记住 FOR 循环自动开关游标不用手动OPEN/CLOSE%ROWCOUNT在循环里拿的是当前已处理行数。最后留个实用技巧调试存储过程时在关键位置插DBMS_OUTPUT.PUT_LINE打印中间变量比单步调试快得多。记得先SET SERVEROUTPUT ON输出缓冲区默认可能不够大用SET SERVEROUTPUT ON SIZE UNLIMITED开大一点。
返回列表