第十周(2)输出回文数

*\

烟台大学计算机与控制工程学院

作者:汪莹莉

完成日期:2016年11月7日

问题描述:输出10000以内的所有回文数

程序:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i,j,m,t;
    for(i=1; i<10; i++)
        printf("%d\t",i);
    for(i=1; i<10; i++)
    {
        j=i*10+i;
        printf("%d\t",j);
    }
    for(i=100; i<1000; i++)
    {
        m=i%10;
        t=i/100;
        if(m==t)
            printf("%d\t",i);
    }
    for(i=10; i<=99; i++)
    {
        j=(i%10)*10+i/10;
        printf("%d\t",i*100+j);
    }
    return 0;
}

 

运行结果:

知识点总结:10000以内的回文数分为一位的、两位的和三位的、四位的。一位的直接输出,两位的需要乘以十,三位和四位的需要用到循环

学习心得:明确了回文数的概念,对于不同位数的回文数有不同的算法

declare v_1 date := TO_DATE('20250301', 'YYYYMMDD'); v_start date; v_end date := trunc(sysdate); v_current date; v_sql varchar2(5000); begin v_start :=trunc(v_1); for i in 0..(v_end-v_start) loop v_current := v_start+i; v_sql := 'merge into PURE_AVG_AMOUNT dest using (with t1 as (SELECT a.*,CASE WHEN a.COUNTRY_CODE = ''tz'' THEN a.IN_FORCE_DATE + 3 / 24 WHEN a.COUNTRY_CODE = ''ke'' THEN a.IN_FORCE_DATE + 3 / 24 WHEN a.COUNTRY_CODE = ''ci'' THEN a.IN_FORCE_DATE WHEN a.COUNTRY_CODE = ''ph'' THEN a.IN_FORCE_DATE + 8 / 24 END AS NEW_DATE FROM LOAN_BORROW_INFO_TEST a WHERE a.COUNTRY_CODE <> ''gh'' AND a.RISK_SERIAL_NO <> ''googleplay'' AND a.ARCHIVED=1 and a.IN_FORCE_DATE is not null), t2 as (select distinct phone,country_code,NEW_DATE from t1 where TRUNC(NEW_DATE)=TO_DATE(''' || TO_CHAR(v_current, 'YYYYMMDD') || ''', ''YYYYMMDD'')and user_type_product=0), t3 as ( select t1.NEW_DATE,t1.REPAYMENT_AMOUNT from t2 left join t1 on t2.phone=t1.phone and t2.country_code=t1.country_code and t1.NEW_DATE>=t2.NEW_DATE and t1.new_date is not null), t4 as( select week_num,TO_DATE(''' || TO_CHAR(v_current, 'YYYYMMDD') || ''', ''YYYYMMDD'') as pure_in_force_date,sum(REPAYMENT_AMOUNT/100)/count(1) AS avg_AMOUNT from (SELECT REPAYMENT_AMOUNT, TRUNC((NEW_DATE - MIN(NEW_DATE) OVER ()) / 7)+1 AS week_num, MIN(NEW_DATE) OVER () + TRUNC((NEW_DATE - MIN(NEW_DATE) OVER ()) / 7) * 7 AS week_start, MIN(NEW_DATE) OVER () + TRUNC((NEW_DATE - MIN(NEW_DATE) OVER ()) / 7) * 7 + 6 AS week_end FROM t3 WHERE NEW_DATE BETWEEN TO_DATE(''2025-03-01'', ''YYYY-MM-DD'') AND TRUNC(ADD_MONTHS(SYSDATE, 12), "YYYY") - 1) GROUP BY week_num ORDER BY week_num), t5 as(select * from t4 pivot(sum(round(avg_AMOUNT,6)) for week_num IN (1 AS "第一", 2 AS "第二", 3 AS "第三", 4 AS "第四", 5 AS "第五", 6 AS "第六", 7 AS "第七", 8 AS "第八", 9 AS "第九", 10 AS "第十", 11 AS "第十", 12 AS "第十", 13 AS "第十", 14 AS "第十", 15 AS "第十", 16 AS "第十", 17 AS "第十", 18 AS "第十", 19 AS "第十", 20 AS "第二十", 21 AS "第二十一", 22 AS "第二十二", 23 AS "第二十三", 24 AS "第二十四", 25 AS "第二十五", 26 AS "第二十六", 27 AS "第二十七", 28 AS "第二十八", 29 AS "第二十九", 30 AS "第三十", 31 AS "第三十一", 32 AS "第三十二", 33 AS "第三十三", 34 AS "第三十四", 35 AS "第三十五", 36 AS "第三十六", 37 AS "第三十七", 38 AS "第三十八", 39 AS "第三十九", 40 AS "第四十", 41 AS "第四十一", 42 AS "第四十二", 43 AS "第四十三"))) select t5.* from t5) src on (dest.PURE_IN_FORCE_DATE=src.pure_in_force_date and dest.COUNTRY_CODE=src.COUNTRY_CODE WHEN MATCHED THEN UPDATE SET dest."第一" = src."第一",dest."第二" = src."第二",dest."第三" = src."第三",dest."第四" = src."第四",dest."第五" = src."第五",dest."第六" = src."第六",dest."第七" = src."第七",dest."第八" = src."第八",dest."第九" = src."第九",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第十" = src."第十",dest."第二十" = src."第二十",dest."第二十一" = src."第二十一",dest."第二十二" = src."第二十二",dest."第二十三" = src."第二十三",dest."第二十四" = src."第二十四",dest."第二十五" = src."第二十五",dest."第二十六" = src."第二十六",dest."第二十七" = src."第二十七",dest."第二十八" = src."第二十八",dest."第二十九" = src."第二十九",dest."第三十" = src."第三十",dest."第三十一" = src."第三十一",dest."第三十二" = src."第三十二",dest."第三十三" = src."第三十三",dest."第三十四" = src."第三十四",dest."第三十五" = src."第三十五",dest."第三十六" = src."第三十六",dest."第三十七" = src."第三十七",dest."第三十八" = src."第三十八",dest."第三十九" = src."第三十九",dest."第四十" = src."第四十",dest."第四十一" = src."第四十一",dest."第四十二" = src."第四十二",dest."第四十三" = src."第四十三" WHEN NOT MATCHED THEN INSERT ( pure_in_force_date, "第一","第二","第三","第四","第五","第六","第七","第八","第九","第十","第十","第十","第十","第十","第十","第十","第十","第十","第十","第二十","第二十一","第二十二","第二十三","第二十四","第二十五","第二十六","第二十七","第二十八","第二十九","第三十","第三十一","第三十二","第三十三","第三十四","第三十五","第三十六","第三十七","第三十八","第三十九","第四十","第四十一","第四十二","第四十三" ) VALUES ( src.pure_in_force_date, src."第一",src."第二",src."第三",src."第四",src."第五",src."第六",src."第七",src."第八",src."第九",src."第十",src."第十",src."第十",src."第十",src."第十",src."第十",src."第十",src."第十",src."第十",src."第十",src."第二十",src."第二十一",src."第二十二",src."第二十三",src."第二十四",src."第二十五",src."第二十六",src."第二十七",src."第二十八",src."第二十九",src."第三十",src."第三十一",src."第三十二",src."第三十三",src."第三十四",src."第三十五",src."第三十六",src."第三十七",src."第三十八",src."第三十九",src."第四十",src."第四十一",src."第四十二",src."第四十三" ))'; EXECUTE IMMEDIATE v_sql; END LOOP; end; 报[65000][6502] ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 ORA-06512: 在 line 11 https://docs.oracle.com/error-help/db/ora-065 ...
最新发布
06-06
<think>首先,我需要理解用户的问题。用户正在询问如何在OraclePL/SQL中避免ORA-06502错误,特别是在执行动态生成的MERGE语句时。错误提示是“数字或值错误:字符串缓冲区太小”,这通常意味着在PL/SQL操作中,变量或缓冲区的大小不足以容纳分配的数据。我之前的回复处理了相同的错误,用户现在又提及,所以我要确保我的回答相关有用。用户提到了具体的场景:在执行长MERGE语句时出现错误。回顾用户提供的引用:-引用[1]描述了ORA-06502错误,指出在递归SQL级别1上发生缓冲区太小的问题。-引用[2]提到在相同数据库上相同SQL的执行结果不同,可能是因为环境因素。用户的需求是避免此错误,特别是在动态SQL的上下文中。关键原因和解决方案:1.**原因**:ORA-06502错误通常发生在PL/SQL变量(如VARCHAR2)被分配给超过其声明的最大大小的值。例如,如果声明一个变量为VARCHAR2(100),但分配200个字符的字符串。2.**动态SQL**:当动态生成SQL时(如使用EXECUTEIMMEDIATE),生成的SQL字符串可能过长,超出了PL/SQL变量的大小限制。3.**MERGE语句**:MERGE语句可能非常长,特别是当涉及多个列或条件时。解决方案:-**增加变量大小**:确保用于存储动态SQL字符串的变量足够大。Oracle中,PL/SQL的VARCHAR2默认最大大小是32767字节。应该使用VARCHAR2(32767)或更大(如果使用扩展数据类型)。-**使用CLOB**:对于超过32767字节的字符串,需要使用CLOB(字符大对象)类型。可以使用DBMS_LOB包来处理CLOB。-**检查错误位置**:确认错误发生在哪里。是构建字符串时,还是执行SQL时?用户说在动态生成和执行时。-**环境因素**:如引用[2]中提到的,环境差异可能导致相同代码在不同地方表现不同。原因可能包括数据库设置(如NLS设置)、隐式转换或PL/SQL引擎版本差异。-**调试技巧**:输出动态SQL字符串的长度以诊断;确保数据类型匹配;使用绑定变量避免隐式转换问题。基于我的知识和用户场景的建议:1.**优化变量声明**:用VARCHAR2(32767)或CLOB存储动态SQL。2.**动态SQL构建**:避免不必要的数据,考虑分割长SQL或用批次处理。3.**错误处理**:添加异常处理来捕获并记录错误细节。4.**测试**:在不同环境下测试以确保一致性。回答结构:-保持清晰和结构。-使用中文,如系统指令要求。-包括相关问题和生成问题部分。-添加引用标识。最终输出格式:-先解释问题和原因。-然后提供具体步骤或方法。-添加代码示例(PL/SQL相关)。-生成相关问题。生成相关问题:-确保问题相关和有意义。</think> ### 避免Oracle PL/SQL中ORA-06502错误(数字或值错误:字符串缓冲区太小)的解决方案 在Oracle PL/SQL中执行动态生成的MERGE语句时遇到的ORA-06502错误("字符串缓冲区太小")通常是由于存储SQL字符串的变量大小不足以容纳生成的SQL文本引起的。在PL/SQL中,VARCHAR2类型的默认最大大小为32767字节(约32KB),但动态SQL(如使用EXECUTE IMMEDIATE)可能超出此限制,导致缓冲区溢出错误。此错误在引用[1]和[2]中也描述了类似场景:环境差异或SQL长度变化可能导致相同代码在不同系统中表现不一致。以下是针对您的动态MERGE语句场景的逐步解决方案。 #### 错误原因分析 - **核心问题**:当动态生成的SQL字符串长度超出变量声明的最大大小时(例如,如果变量定义为VARCHAR2(4000),但生成的MERGE语句超过4000字节),PL/SQL引擎会抛出ORA-06502错误。 - **动态SQL风险**:MERGE语句通常较长,尤其是涉及多列、JOIN条件或复杂逻辑时。动态构建SQL(使用字符串拼接)会加剧这一问题。 - **环境差异影响**:如引用[2]所述,即使相同SQL在不同环境下出错,可能是因为: - 数据库参数设置不同(如`VARCHAR2`或`CLOB`处理)。 - 隐式数据类型转换导致额外开销。 - PL/SQL引擎版本差异(某些环境隐式优化或截断字符串)。 - **递归SQL问题**:引用[1]指出错误可能在"递归SQL级别"发生,这常与嵌套动态SQL或存储过程调用相关。 #### 避免错误的实用方法 以下方法基于Oracle最佳实践,确保动态SQL操作安全可靠。优先增加缓冲区大小,并结合错误处理和优化来预防ORA-06502。 1. **增加字符串变量的大小上限** - 在PL/SQL中,使用最大允许的`VARCHAR2`大小(32767字节)声明变量。确保变量大小足以容纳完整的MERGE语句。 ```plsql DECLARE v_sql VARCHAR2(32767); -- 最大VARCHAR2大小 BEGIN -- 动态生成MERGE语句 v_sql := 'MERGE INTO target_table t USING source_table s ON (t.id = s.id) WHEN MATCHED THEN UPDATE SET ...'; -- 实际SQL构建逻辑 EXECUTE IMMEDIATE v_sql; END; / ``` - **注意**:如果您的MERGE语句可能超出32KB,立即切换到`CLOB`类型(无大小限制)。使用`DBMS_LOB`包处理大文本。 ```plsql DECLARE v_clob CLOB; -- 使用CLOB类型 BEGIN DBMS_LOB.CREATETEMPORARY(v_clob, TRUE); -- 使用DBMS_LOB.WRITE或APPEND构建SQL DBMS_LOB.WRITEAPPEND(v_clob, LENGTH('MERGE INTO ...'), 'MERGE INTO ...'); EXECUTE IMMEDIATE TO_CHAR(v_clob); -- 执行CLOB内容 DBMS_LOB.FREETEMPORARY(v_clob); -- 清理临时CLOB END; / ``` 2. **优化动态SQL构建以减少长度** - 分割长SQL语句:将大型MERGE分解为多个子查询或小批次操作,避免单一字符串过长。 - 例如,分批处理ID或ROWID范围,使用循环执行。 ```plsql DECLARE v_sql VARCHAR2(32767); BEGIN FOR i IN 1..total_batches LOOP v_sql := 'MERGE INTO target_table ... WHERE id BETWEEN ' || start_id || ' AND ' || end_id; EXECUTE IMMEDIATE v_sql; END LOOP; END; / ``` - 减少不必要的字符串:避免在动态SQL中包含冗余列或条件;使用绑定变量(如`:var`)而不是硬编码值以减少长度和隐式转换风险。 3. **添加错误处理和诊断** - 在代码中加入异常块捕获ORA-06502错误,并输出SQL长度或内容以诊断。 ```plsql DECLARE v_sql VARCHAR2(32767); BEGIN v_sql := ...; -- 生成MERGE语句 EXECUTE IMMEDIATE v_sql; EXCEPTION WHEN OTHERS THEN IF SQLCODE = -6502 THEN -- 捕获ORA-06502错误 DBMS_OUTPUT.PUT_LINE('SQL长度: ' || LENGTH(v_sql) || ' 字节'); -- 输出长度诊断 RAISE; -- 重新抛出错误 END IF; END; / ``` - **诊断工具**:运行查询检查SQL长度:`SELECT LENGTH('您的MERGE语句') FROM dual;` 确认是否超限。 4. **检查和调整数据库设置** - 确保所有环境参数一致:核对`init.ora`或`spfile`参数如`max_string_size`(设置为EXTENDED模式,允许VARCHAR2最大为32767字节)。 ```sql -- 检查参数 SELECT name, value FROM v$parameter WHERE name LIKE '%string%'; -- 如需修改(需重启数据库) ALTER SYSTEM SET max_string_size = EXTENDED SCOPE = SPFILE; ``` - 避免隐式转换:在动态SQL中明确使用`TO_CHAR`或`CAST`确保数据类型匹配(引用[2]强调这可能导致不同环境行为差异)。 5. **替代方案:使用DBMS_SQL包** - 对于极长SQL,`DBMS_SQL`包提供更好的控制,支持CLOB执行。 ```plsql DECLARE c INTEGER; ret INTEGER; v_clob CLOB; BEGIN c := DBMS_SQL.OPEN_CURSOR; DBMS_LOB.CREATETEMPORARY(v_clob, TRUE); -- 构建和写入CLOB内容 DBMS_SQL.PARSE(c, v_clob, DBMS_SQL.NATIVE); ret := DBMS_SQL.EXECUTE(c); DBMS_SQL.CLOSE_CURSOR(c); DBMS_LOB.FREETEMPORARY(v_clob); END; / ``` #### 注意事项 - **环境一致性**:引用[2]强调相同SQL在不同环境表现不同时,重点检查数据库版本、NLS设置和用户权限。建议在开发和测试环境模拟错误[^1]。 - **性能开销**:使用CLOB或分批处理会增加资源消耗;仅在必要时使用,并监控SQL执行计划。 - **一般建议**:在开发阶段预先计算SQL长度(例如,用`SELECT LENGTH(sql_text) FROM ...`),并设计变量大小冗余10-20%。 如果错误持续,提供更多上下文(如MERGE语句样本或PL/SQL块),我可以协助进一步诊断。此方案已参考您的引用内容[^1][^2],并基于Oracle文档最佳实践优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值