动态Sql
一些应用程序必须在运行时接受(或构建)并处理各种SQL语句 这种在程序执行临时生成的 SQL 语句叫动态 SQL 语句. 利用动态 SQL 来编写 Pro*C 程序的方法叫动态 SQL 技术.。也就是说SQL语句的组成直到运行时才知道。这样的语句可以(而且可能会)在执行过程中发生变化。
当出现下列情况, 就需要使用动态 SQL 技术:
1. SQL 语句的文本未知.
2. 宿主变量的个数未知。
3. 宿主变量的数据类型未知。
4. 引用的数据库对象未知, 如列, 索引, 序列, 表, 用户名和视图.
方法一
只能执行非查询语句(非select), 且在非查询动态 SQL 语句内不能包含输入宿主变量占位符
- demo1
//> update dept set loc= ‘bj’ where deptno=89
//>insert into dept values(88, ‘CJ’, ‘TJ’)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sqlca.h"
#include "oraca.h"
//定义宿主变量
EXEC SQL BEGIN DECLARE SECTION;
char *serverid = "c##scott/root";
char Sqlstatements[1024];
char *pSql;
EXEC SQL END DECLARE SECTION;
extern sqlgls(char * , size_t *, size_t * );
extern sqlglmt(void *,char *,size_t *,size_t *);
int connet();
void doerr();
//非select语言,无宿主变量
int main()
{
int ret = 0;
char inputchar;
memset(Sqlstatements, 0, sizeof(Sqlstatements));
pSql = NULL;
EXEC SQL WHENEVER SQLERROR DO doerr();
connet();
pSql = mySql;
//循环处理sql语言
for(;;)
{
printf("\nplease enter sql(not select ): ");
gets(mySql);
//scanf("%s", mySql); --空格截断
printf("mysql>%s\n", mySql);
printf("任意键继续执行....\n");
getchar();
EXEC SQL EXECUTE IMMEDIATE :pSql;
EXEC SQL COMMIT;
printf("continue?\n");
scanf("%c", &inputchar);
fflush(stdin);
if (inputchar=='n' || inputchar=='N')
{
break;
}
}
EXEC SQL COMMIT WORK RELEASE;
return ret ;
}
int connet()
{
int ret = 0;
//连接数据库
EXEC SQL connect :serverid;
if (sqlca.sqlcode != 0)
{
ret = sqlca.sqlcode;
return ret;
}
else
{
printf("connect ok...\n");
}
return ret;
}
void doerr()
{
char szerrbuf[120];
size_t outputlen, inputlen = 120;
unsigned int ret = 0;
//出错时,可以把错误SQL语言给打印出来
EXEC SQL WHENEVER SQLERROR CONTINUE;
ret = sqlgls(szerrbuf, &inputlen, &outputlen);
printf("SQL:%.*s\n", inputlen, szerrbuf);
printf("提示:%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK RELEASE;
exit(1);
}