本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
BEGIN
SELECT
TO_CHAR
(
SYSDATE
,
'yyyy-mm-dd hh24:mi:ss'
)
INTO
CURRENT_TIME
FROM
DUAL
;
DBMS_OUTPUT
.
PUT_LINE
(
'当前时间:'
||
CURRENT_TIME
)
;
END
;
当前时间:
2020
-
05
-
30
16
:
44
:
37
2 IF判断
写一个IF语句,判断是否存在某张表,如果存在则删除。
CREATE OR REPLACE PROCEDURE TEST AS
N_TABLE_NAME VARCHAR2(32);
NUM INT;
BEGIN
N_TABLE_NAME := 'TEST_AAA';
SELECT COUNT(1) INTO NUM FROM ALL_TABLES WHERE TABLE_NAME = N_TABLE_NAME;
DBMS_OUTPUT.PUT_LINE('被查询表数量(1为有):' || NUM);
IF NUM = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE ' || N_TABLE_NAME;
DBMS_OUTPUT.PUT_LINE('表存在,已删除!');
END IF;
END;
被查询表数量(1为有):1
表存在,已删除!
3 WHILE循环
写一个WHILE循环,用来动态拼接部分SQL(关联条件部分)。
CREATE OR REPLACE PROCEDURE TEST AS
STR VARCHAR2(128);
SIGNS INT;
SI_MAX INT;
CURRENT_VALUE VARCHAR2(32);
CALCULATED INT;
CONDITIONS VARCHAR2(128);
ALIAS VARCHAR2(16);
F_ALI VARCHAR2(16);
L_ID VARCHAR2(1280);
BEGIN
ALIAS := 'Z';
F_ALI := 'B';
L_ID := '1002';
STR := 'PROJECTID,ID,YEAR_DATE,TIME';
STR := STR || ',';
DBMS_OUTPUT.PUT_LINE('待拼接的字段:' || STR);
SELECT REGEXP_COUNT(STR,',') INTO SIGNS FROM DUAL;
DBMS_OUTPUT.PUT_LINE('逗号数量:' || SIGNS);
SI_MAX := SIGNS;
WHILE SIGNS > 0 LOOP
SELECT SUBSTR(STR,1,INSTR(STR,',') - 1 ) INTO CURRENT_VALUE FROM DUAL;
SELECT SUBSTR(STR,INSTR(STR,',') + 1) INTO STR FROM DUAL;
DBMS_OUTPUT.PUT_LINE('当前循环数值:' || SIGNS);
DBMS_OUTPUT.PUT_LINE('当前取到的字段:' || CURRENT_VALUE);
DBMS_OUTPUT.PUT_LINE('当前未取到的字段:' || STR);
SELECT MOD(SIGNS,2) INTO CALCULATED FROM DUAL;
DBMS_OUTPUT.PUT_LINE('0为前者,1位后者:' || CALCULATED);
IF CALCULATED = 0 THEN
IF SIGNS = SI_MAX THEN
CONDITIONS := CONDITIONS || F_ALI || L_ID || '.' || CURRENT_VALUE;
CONDITIONS := CONDITIONS || 'AND ' || F_ALI || L_ID || '.' || CURRENT_VALUE;
END IF;
CONDITIONS := CONDITIONS || ' = ' || ALIAS || '.' || CURRENT_VALUE || ' ';
END IF;
SIGNS := SIGNS - 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('拼接好的SQL(关联条件字符串):' || CONDITIONS);
END;
待拼接的字段:PROJECTID,ID,YEAR_DATE,TIME,
逗号数量:4
当前循环数值:4
当前取到的字段:PROJECTID
当前未取到的字段:ID,YEAR_DATE,TIME,
0为前者,1位后者:0
当前循环数值:3
当前取到的字段:ID
当前未取到的字段:YEAR_DATE,TIME,
0为前者,1位后者:1
当前循环数值:2
当前取到的字段:YEAR_DATE
当前未取到的字段:TIME,
0为前者,1位后者:0
当前循环数值:1
当前取到的字段:TIME
当前未取到的字段:
0为前者,1位后者:1
拼接好的SQL(关联条件字符串):B1002.PROJECTID = Z.ID AND B1002.YEAR_DATE = Z.TIME
4 FOR循环
通过游标写一个简单的FOR循环。
CREATE OR REPLACE PROCEDURE TEST AS
CURSOR DATA IS SELECT * FROM (SELECT a.*,ROWNUM RN FROM IEW_INDEX a ORDER BY ID) WHERE RN <= 10;
BEGIN
FOR TEMP IN DATA LOOP
DBMS_OUTPUT.PUT_LINE(TEMP.ID || ',' || TEMP.INDEX_NAME);
END LOOP;
END;
1001,本年收入增长
1002,累计收入增长
1003,本年成本增长
1004,累计成本增长
1005,预测投资总额
1013,实际投资总额
1014,预测完工时间
1015,实际完工时间
1016,预测开工时间
1017,实际开工时间
5 项目实例
前边铺垫了那么多,现在附上项目实例,把各种操作整合到一起看一下效果。
CREATE OR REPLACE PROCEDURE TEST AS
N_TABLE_NAME VARCHAR2(32);
SIGNS INT;
SI_MAX INT;
ALIAS VARCHAR2(16);
F_ALI VARCHAR2(16);
NUM INT;
CURRENT_VALUE VARCHAR2(32);
TARGET_RESULTS VARCHAR2(25600);
STR VARCHAR2(128);
CONDITIONS VARCHAR2(128);
QUERY_ITEMS VARCHAR2(128);
CALCULATED INT;
CURSOR DATA IS SELECT * FROM (SELECT a.*,ROWNUM RN FROM IEW_INDEX a ORDER BY ID) WHERE RN <= 50;
BEGIN
ALIAS := 'Z';
F_ALI := 'B';
N_TABLE_NAME := 'BBB';
SELECT COUNT(1) INTO NUM FROM ALL_TABLES WHERE TABLE_NAME = N_TABLE_NAME;
IF NUM = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE ' || N_TABLE_NAME;
END IF;
TARGET_RESULTS := 'CREATE TABLE ' || N_TABLE_NAME || ' AS ';
TARGET_RESULTS := TARGET_RESULTS || 'SELECT ' || ALIAS || '.* ';
FOR TEMP IN DATA LOOP
TARGET_RESULTS := TARGET_RESULTS || ',B' || TEMP.ID || '.A' || TEMP.ID || ' ';
END LOOP;
TARGET_RESULTS := TARGET_RESULTS || 'FROM (SELECT a.PRO_NAME,a.CLASS_NAME,a.ID,a.MAIN_DATA_PRO_CODE,b.TIME ';
TARGET_RESULTS := TARGET_RESULTS || 'FROM IEW_V_PRO_USER a LEFT JOIN (SELECT DISTINCT PROJECTID,TIME from V_IEW_ACC_DETAIL_DATA WHERE TIME <= '''||2020||''') b ON a.ID = b.PROJECTID ';
TARGET_RESULTS := TARGET_RESULTS || 'LEFT JOIN (SELECT T.*,(CASE WHEN t.START_YEAR IS NULL THEN bussiness_year+ORIGIN_YEAR ELSE START_YEAR END) begin_year,'''||2020||''' END_YEAR ';
TARGET_RESULTS := TARGET_RESULTS || 'FROM (SELECT A.PROJECTNAME,B.ID,B.MAIN_DATA_PRO_CODE,A.PERIOD,A.ORIGIN_YEAR,A.PERIOD_TIME,';
TARGET_RESULTS := TARGET_RESULTS || '(SELECT TO_NUMBER(SUBSTR(NVL(VALUE,'''||1900||'''),0,4)) bussiness_year ';
TARGET_RESULTS := TARGET_RESULTS || 'FROM IEW_ACTUAL_DATA WHERE ACC_CODE = '''||'C000005'||''' AND PROJECTID = B.ID) bussiness_year,A.START_YEAR,D.TIME,D.VALUE,C.RESULT ISWARN ';
TARGET_RESULTS := TARGET_RESULTS || 'FROM IEW_MODPRICE_PERIOD A LEFT JOIN IEW_V_PRO_USER B ON A.PROJECTNAME = B.PROJECTNAME ';
TARGET_RESULTS := TARGET_RESULTS || 'LEFT JOIN (SELECT * FROM IEW_ACTUAL_DATA D WHERE D.TIME < '''||2020||''' AND D.ACC_CODE = '''||'C000114'||''')D ';
TARGET_RESULTS := TARGET_RESULTS || 'ON D.PROJECTID = B.ID LEFT JOIN (SELECT * FROM IEW_ACC_WARN_DATA_FINAL WHERE DATA_VER_ID = 1 AND RES_ACC_CODE = '''||'income002'||''' ) C ';
TARGET_RESULTS := TARGET_RESULTS || 'ON B.ID = C.PROJECTID AND C.YEAR_DATE = D.TIME) T ORDER BY ID,PROJECTNAME,TIME )C ON A.ID = C.ID AND B.TIME = C.TIME ORDER BY a.ID,b.TIME';
TARGET_RESULTS := TARGET_RESULTS || ') ' || ALIAS || ' ';
FOR TEMP IN DATA LOOP
STR := TEMP.ASSOCIATION;
STR := STR || ',';
SELECT REGEXP_COUNT(STR,',') INTO SIGNS FROM DUAL;
SI_MAX := SIGNS;
CONDITIONS := '';
QUERY_ITEMS := '';
WHILE SIGNS > 0 LOOP
SELECT SUBSTR(STR,1,INSTR(STR,',') - 1 ) INTO CURRENT_VALUE FROM DUAL;
SELECT SUBSTR(STR,INSTR(STR,',') + 1) INTO STR FROM DUAL;
SELECT MOD(SIGNS,2) INTO CALCULATED FROM DUAL;
IF CALCULATED = 0 THEN
IF SIGNS = SI_MAX THEN
CONDITIONS := CONDITIONS || F_ALI || TEMP.ID || '.' || CURRENT_VALUE;
QUERY_ITEMS := QUERY_ITEMS || CURRENT_VALUE;
CONDITIONS := CONDITIONS || 'AND ' || F_ALI || TEMP.ID || '.' || CURRENT_VALUE;
QUERY_ITEMS := QUERY_ITEMS || ',' || CURRENT_VALUE;
END IF;
CONDITIONS := CONDITIONS || ' = ' || ALIAS || '.' || CURRENT_VALUE || ' ';
END IF;
SIGNS := SIGNS - 1;
END LOOP;
TARGET_RESULTS := TARGET_RESULTS || 'LEFT JOIN (SELECT DISTINCT ' || QUERY_ITEMS || ',' || TEMP.QUERY_CONTENT || ' AS A' || TEMP.ID || ' FROM ' || TEMP.TABLE_NAME || ' WHERE ' || TEMP.PARAMETER || ') B' || TEMP.ID || ' ON ' || CONDITIONS;
END LOOP;
EXECUTE IMMEDIATE TARGET_RESULTS;
DBMS_OUTPUT.PUT_LINE('目标结果SQL:' || chr(13) || TARGET_RESULTS);
END;
由于输出结果太长了,我这里就附上一张图片吧。
6 知识点
SELECT …INTO
在数据库中进行查询,并将得到的结果赋值给变量。
要求:查询的结果集中==只能有1行==。
:=
给变量赋值。
||
字符串连接符号,相当于Java重的“+”,将两个字符或字符串连接起来。
DBMS_OUTPUT.PUT_LINE()
打印的语句或变量。
EXECUTE IMMEDIATE
执行动态语句,可以用于执行动态拼接好的SQL。
CURSOR IS
游标,配合FRO使用。