当前位置:文档之家› 动态SQL与静态SQL

动态SQL与静态SQL

个数和数据类型必须是已知的.例如: 'INSERT INTO EMP (ENAME, JOB) VALUES (:emp_name, :job_title)' 'DELETE FROM EMP WHERE EMPNO = :emp_number'
3. 方法三 使用 DECLARE, OPEN, FETCH, CLOSE cursor 可以使用 select,并且 select
/* dyn_stmt now contains the text of a SQL statement */ EXEC SQL EXECUTE IMMEDIATE :dyn_stmt; } ... 上面就是方法一,也可以使用下面的代替: EXEC SQL EXECUTE IMMEDIATE 'REVOKE RESOURCE FROM MILLER'; 但是 EXECUTE IMMEDIATE 在每次执行之前都要进行解析,所以方法一最 适用的是一次性 sql.一般用来执行 DDL
sprintf(SqlStr,"SELECT a.SERV_ID,a.OFFER_ID,TO_CHAR(a.EFF_DATE,'YYYYMMDD')
\
FROM PRODUCT_OFFER_INSTANCE a,PRODUCT_OFFER b \
பைடு நூலகம்
WHERE
TO_CHAR(a.EFF_DATE,'YYYYMMDD')=TO_CHAR(SYSDATE,'YYYYMMDD')
printf("查询销售品更换用户出错,查找出错原因,并重新执行!"); goto end_change; } for(;;)
{ EXEC SQL fetch curSql INTO :serv_id, :offer_id,:eff_date;
if (SQLCODE!=OK) {
if (SQLCODE==NOTFOUND) break; EXEC SQL CLOSE curSql; printf("取销售品更换的用户出错! [SQLCODE=%d][SQLERRMSG=%s]\n",SQLCODE,SQLERRMSG); goto end_change; }
2.8.2. 方法二
语法:EXEC SQL PREPARE statement_name FROM { :host_string | string_literal };
Prepare 一次,但是可以循环执行很多次.
2.8.3. 方法三
语法: PREPARE statement_name FROM { :host_string | string_literal };
|ABSOLUTE fetch_offset ]
cursor_name INTO
host_variable_list;
CLOSE cursor_name;
PREPARE:
分析一个 sql 语句并且给他命名.
DECLARE
声明一个游标变量,并给他一个名字,最后把他和一个查询语句关联起来..
OPEN
分配一个游标变量,然后把所有的输入变量和他绑定,最后执行查询语句.
values(to_number(:sV_Total_date),to_number(:sV_LoginAccept),:sIn_Op_code,'0',0,\ 'ZZ',to_number(:sIn_Cust_id),'Z',:sIn_Org_code,\ :sIn_Work_no,sysdate,:sIn_Op_note,:sIn_Ip_Addr)",sV_YYYYMM);
2.7. 如何选择动态 sql
2.8. 方法举例和分析
2.8.1. 方法一
char dyn_stmt[132]; ... for (;;) {
printf("Enter SQL statement: "); gets(dyn_stmt); if (*dyn_stmt == '\0')
break;
\
and a.offer_id=b.offer_id
\
and b.offer_type=10 \
and a.exp_date>sysdate");
EXEC SQL PREPARE SqlStmt FROM :SqlStr; EXEC SQL declare curSql cursor for SqlStmt; EXEC SQL OPEN curSql; if(SQLCODE!=0) {
'000',0,0,0 ,0,0,0,0,0,0,'0','0','%s', '%s', '0','0')", atoi(total_date)/100,
vIdNo, total_date, login_accept, sm_code, belong_code, iPhoneNo, belong_code, login_no, op_code, op_time, vRetMsg, vRetMsg);
EXEC SQL PREPARE stm_shortaddmode1 FROM :temp_sql; EXEC SQL EXECUTE stm_shortaddmode1;
other_fee,hand_fee,deposit,back_flag,encrypt_fee,system_note,op_note,group_id,org_i d)\
values(%s,'%s',%d,'%s','%s','%s','%s','%s','%s',to_date('%s','yyyymmdd hh24:mi:ss'),\
字段的个数,变量占位符,变量类型在编译时必须是已知的.例如: 'SELECT DEPTNO, MIN(SAL), MAX(SAL) FROM EMP GROUP BY
DEPTNO' 'SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :dept_number' 4. 方法四 这种方法可以在运行时确定 select 个数,变量个数,变量数据类型.例如: 'INSERT INTO EMP (<unknown>) VALUES (<unknown>)' 'SELECT <unknown> FROM EMP WHERE DEPTNO = 20'
printf("insert wLoginOpr%s' sql_str = [%s]\n",sV_YYYYMM,sql_str); EXEC SQL PREPARE ins_stmt From :sql_str; EXEC SQL EXECUTE ins_stmt using :sV_Total_date,:sV_LoginAccept,:sIn_Op_code,:sIn_Cust_id,:sIn_Org_code,:sIn_W ork_no,:sIn_Op_note,:sIn_Ip_Addr;
}
错误写法: sprintf(temp_sql, "insert into wChg%d(id_no,total_date,login_accept,sm_code,belong_code,phone_no,org_code,\
login_no,op_code,op_time,machine_code,cash_pay,check_pay,sim_fee,machine_fee,innet_ fee,choice_fee,\
2. ORACLE 动态 sql
2.1. 什么是动态 sql
大部分程序在编译时已经知道更新哪个表,哪个字段,和字段的数据类型. 但是,还有一些程序必须处理不确定的 sql,例如通用报表必须使用不同的 select 语句.这样的话 sql 只有到运行的时候才能确定,这样的语句就叫做动态 sql. 和静态 sql 不一样,动态语句可以存储在字符串里,也可以从文件中读取,还能在运 行的时候通过用户输入拼装出来.
动态 sql 在执行效率上,对于重复的 sql 确实要高于静态,但是会带来编码上的 难度.
例子:
正确写法: init(TmpSqlStr); sprintf(TmpSqlStr,"select nvl(sum(pay_money),0) from wpay%6d where contract_no=:v1 ", in_year_month); EXEC SQL EXECUTE
BEGIN EXECUTE IMMEDIATE :TmpSqlStr INTO :value_money using :in_contract_no;
END; END-EXEC;
sprintf(sql_str,"insert into wLoginOpr%s( \ total_date,login_accept,op_code,pay_type,pay_money, \ sm_code,id_no,phone_no,org_code,login_no,op_time,op_note,IP_ADDR) \
然后,执行这些 sql,根据 sql 更新,删除.这些 sql 可以用不同的新值替换,然后重 复执行.
2.6. 使用动态 sql 的方法
1. 方法一 使用 EXECUTE IMMEDIATE,不能包含 select,不能包含带有变量的占位
符.例如: 'DELETE FROM EMP WHERE DEPTNO = 20' 'GRANT SELECT ON EMP TO scott' 2. 方法二 使用 PREPARE 和 EXECUTE,sql 不能包含 select,在编译的时候变量的
相关主题