Oracle PL/SQL实现凯撒密码字符串加密及UPDATE调用存储过程需求
Oracle PL/SQL实现类凯撒密码(+1偏移)加密功能
嘿,我来帮你搞定这个需求!先明确咱们要实现的规则:每个字母/数字按+1偏移循环,大写转大写、小写转小写,数字循环,其他字符(分隔符、空格啥的)不动,空字符串直接返回空,还要能在UPDATE里用,对吧?
核心实现:自定义加密函数
因为要在UPDATE语句里直接调用,写个自定义函数是最方便的(存储过程没法直接塞到SET子句里,函数就可以直接当列值用)。话不多说,上代码:
CREATE OR REPLACE FUNCTION caesar_plus1(p_input VARCHAR2) RETURN VARCHAR2 IS v_result VARCHAR2(32767); -- 用最大长度的VARCHAR2,兼容各种输入 v_current_char CHAR(1); v_ascii_code NUMBER; BEGIN -- 空输入直接返回空 IF p_input IS NULL THEN RETURN NULL; END IF; -- 逐个字符处理 FOR i IN 1..LENGTH(p_input) LOOP v_current_char := SUBSTR(p_input, i, 1); v_ascii_code := ASCII(v_current_char); -- 处理大写字母 A-Z(ASCII 65-90),Z之后回到A IF v_ascii_code BETWEEN 65 AND 90 THEN v_ascii_code := v_ascii_code + 1; IF v_ascii_code > 90 THEN v_ascii_code := 65; END IF; -- 处理小写字母 a-z(ASCII 97-122),z之后回到a ELSIF v_ascii_code BETWEEN 97 AND 122 THEN v_ascii_code := v_ascii_code + 1; IF v_ascii_code > 122 THEN v_ascii_code := 97; END IF; -- 处理数字 0-9(ASCII 48-57),9之后回到0 ELSIF v_ascii_code BETWEEN 48 AND 57 THEN v_ascii_code := v_ascii_code + 1; IF v_ascii_code > 57 THEN v_ascii_code := 48; END IF; -- 其他字符(分隔符、符号等)原样保留 ELSE NULL; END IF; v_result := v_result || CHR(v_ascii_code); END LOOP; RETURN v_result; END caesar_plus1; /
在UPDATE语句里直接用
假设你有个表叫user_data,里面的user_note列是要加密的字符串,直接执行这个UPDATE就行:
UPDATE user_data SET user_note = caesar_plus1(user_note); -- 别忘了提交更改 COMMIT;
封装成批量处理的存储过程
如果你想把批量加密整列的逻辑封装成存储过程(比如给其他同事调用更方便),可以基于上面的函数写一个:
CREATE OR REPLACE PROCEDURE encrypt_table_column(p_table_name IN VARCHAR2, p_column_name IN VARCHAR2) IS v_update_sql VARCHAR2(1000); BEGIN -- 拼接动态SQL,注意表名和列名要合法哦 v_update_sql := 'UPDATE ' || p_table_name || ' SET ' || p_column_name || ' = caesar_plus1(' || p_column_name || ')'; EXECUTE IMMEDIATE v_update_sql; COMMIT; DBMS_OUTPUT.PUT_LINE('搞定!已经加密了表 ' || p_table_name || ' 的 ' || p_column_name || ' 列'); EXCEPTION WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('哎呀出错了:' || SQLERRM); RAISE; -- 把错误抛出去,方便排查 END encrypt_table_column; /
调用这个存储过程的方式:
SET SERVEROUTPUT ON; -- 要开这个才能看到输出信息 BEGIN encrypt_table_column('user_data', 'user_note'); END; /
测试一下效果
用你给的示例输入ABcd012Ab测试函数:
SELECT caesar_plus1('ABcd012Ab') AS encrypted_result FROM DUAL;
返回的结果是BCde123Bc,完全符合要求!
再测测空值和带分隔符的情况:
SELECT caesar_plus1(NULL) AS null_test, caesar_plus1('Hello-World,123') AS symbol_test FROM DUAL;
结果:
null_test:NULL(空值处理正常)symbol_test:Ifmmp-Xpsme,234(-和,完全没动,字母数字都正确偏移)
内容的提问来源于stack exchange,提问作者Максим Ермолаев
相关产品推荐
相关产品推荐

