磨砺技术珠矶,践行数据之道,追求卓越价值 
回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 
[作者 高健@博客园  luckyjackgao@gmail.com]

EXEC SQL CONTEXT... 是Oracle Pro*C的特有的语法,详细信息参见

http://docs.oracle.com/cd/B28359_01/appdev.111/b28427/pc_11thr.htm#i997959

  1. EXEC SQL ENABLE THREADS;
  2. EXEC SQL CONTEXT ALLOCATE :context_var;
  3. EXEC SQL CONTEXT USE { :context_var | DEFAULT};
  4. EXEC SQL CONTEXT FREE :context_var;

所谓context ,被称为runtime context,其实质就是保留连接数据库的信息,保留连接数据库的通道。

官方解释中,使用 exec sql context ,有几种方式:

1 各个进程之间不共享context

事实上,Oracle的官方例子----  Thread_example1.pc,采用的就是这种方式。

各个进程共通处理一堆转账数据,所以它们之间需要考虑对共同数据(文本格式的转账记录)读取时加mutex。

但是,由于每个进程可以自己拥有一个context---数据库通道,故此基本互相不干涉。

我认为这是合理的,也可能是比较高效率的方式。

2 各个进程之间共享一个context

此时,瓶颈出现在此context之上。可以想像一下,通过多线程来处理数据库之外的数据之后,

还是要回到一个共通的数据库通道来排队等候,是否效率并未发挥出来呢。

3 各个进程之间共享多个context

这个是最复杂的,可能也是最没有道理的。1的方式应该更好些。

而且,上述这些,都没有考虑到连接池的作用,也许是这种技术出现的年代是很早的。

为了备忘,记录oracle官方例子如下:

  1. /*
  2. * Name: Thread_example1.pc
  3. *
  4. * Description: This program illustrates how to use threading in
  5. * conjunction with precompilers. The program creates as many
  6. * sessions as there are threads. Each thread executes zero or
  7. * more transactions, that are specified in a transient
  8. * structure called 'records'.
  9. * Requirements:
  10. * The program requires a table 'ACCOUNTS' to be in the schema
  11. * scott/tiger. The description of ACCOUNTS is:
  12. * SQL> desc accounts
  13. * Name Null? Type
  14. * ------------------------------- ------- ------
  15. * ACCOUNT NUMBER(36)
  16. * BALANCE NUMBER(36,2)
  17. *
  18. * For proper execution, the table should be filled with the accounts
  19. * 10001 to 10008.
  20. *
  21. *
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <sqlca.h>
  28.  
  29. #define _EXC_OS_ _EXC__UNIX
  30. #define _CMA_OS_ _CMA__UNIX
  31.  
  32. #ifdef DCE_THREADS
  33. #include <pthread.h>
  34. #else
  35. #include <thread.h>
  36. #endif
  37.  
  38. /* Function prototypes */
  39. void err_report();
  40.  
  41. #ifdef DCE_THREADS
  42. void do_transaction();
  43. #else
  44. void *do_transaction();
  45. #endif
  46.  
  47. void get_transaction();
  48. void logon();
  49. void logoff();
  50.  
  51. #define CONNINFO "scott/tiger"
  52.  
  53. #define THREADS 3
  54.  
  55. struct parameters
  56.  
  57. { sql_context * ctx;
  58. int thread_id;
  59. };
  60.  
  61. typedef struct parameters parameters;
  62.  
  63. struct record_log
  64. {
  65. char action;
  66. unsigned int from_account;
  67. unsigned int to_account;
  68. float amount;
  69. };
  70.  
  71. typedef struct record_log record_log;
  72.  
  73. record_log records[]= { { 'M', , , 12.50 },
  74. { 'M', , , 25.00 },
  75. { 'M', , , 123.00 },
  76. { 'M', , , 125.00 },
  77. { 'M', , , 12.23 },
  78. { 'M', , , 225.23 },
  79. { 'M', , , 0.70 },
  80. { 'M', , , 11.30 },
  81. { 'M', , , 47.50 },
  82. { 'M', , , 125.00 },
  83. { 'M', , , 225.00 },
  84. { 'M', , , 0.70 },
  85. { 'M', , , 11.00 },
  86. { 'M', , , 47.50 },
  87. { 'M', , , 125.00 },
  88. { 'M', , , 225.00 },
  89. { 'M', , , 0.70 },
  90. { 'M', , , 11.00 },
  91. { 'M', , , 47.50 },
  92. { 'M', , , 1034.54}};
  93.  
  94. static unsigned int trx_nr=;
  95.  
  96. #ifdef DCE_THREADS
  97. pthread_mutex_t mutex;
  98. #else
  99. mutex_t mutex;
  100. #endif
  101.  
  102. /*********************************************************************
  103. * Main
  104. ********************************************************************/
  105. main()
  106. {
  107. sql_context ctx[THREADS];
  108.  
  109. #ifdef DCE_THREADS
  110. pthread_t thread_id[THREADS];
  111. pthread_addr_t status;
  112. #else
  113. thread_t thread_id[THREADS];
  114. int status;
  115. #endif
  116.  
  117. parameters params[THREADS];
  118.  
  119. int i;
  120.  
  121. EXEC SQL ENABLE THREADS;
  122.  
  123. EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
  124.  
  125. /* Create THREADS sessions by connecting THREADS times */
  126. for(i=;i<THREADS;i++)
  127. {
  128. printf("Start Session %d....",i);
  129. EXEC SQL CONTEXT ALLOCATE :ctx[i];
  130. logon(ctx[i],CONNINFO);
  131. }
  132.  
  133. /*Create mutex for transaction retrieval */
  134. #ifdef DCE_THREADS
  135. if (pthread_mutex_init(&mutex,pthread_mutexattr_default))
  136. #else
  137. if (mutex_init(&mutex, USYNC_THREAD, NULL))
  138. #endif
  139. {
  140. printf("Can't initialize mutex\n");
  141. exit();
  142. }
  143.  
  144. /*Spawn threads*/
  145. for(i=;i<THREADS;i++)
  146. {
  147. params[i].ctx=ctx[i];
  148. params[i].thread_id=i;
  149.  
  150. printf("Thread %d... ",i);
  151.  
  152. #ifdef DCE_THREADS
  153. if (pthread_create(&thread_id[i],pthread_attr_default,
  154. (pthread_startroutine_t)do_transaction,
  155. (pthread_addr_t) &params[i]))
  156. #else
  157. if (status = thr_create
  158. (NULL, , do_transaction, &params[i], , &thread_id[i]))
  159. #endif
  160. printf("Cant create thread %d\n",i);
  161. else
  162. printf("Created\n");
  163. }
  164.  
  165. /* Logoff sessions....*/
  166. for(i=;i<THREADS;i++)
  167. {
  168. /*wait for thread to end */
  169. printf("Thread %d ....",i);
  170.  
  171. #ifdef DCE_THREADS
  172. if (pthread_join(thread_id[i],&status))
  173. printf("Error when waiting for thread % to terminate\n", i);
  174. else
  175. printf("stopped\n");
  176.  
  177. printf("Detach thread...");
  178.  
  179. if (pthread_detach(&thread_id[i]))
  180. printf("Error detaching thread! \n");
  181. else
  182. printf("Detached!\n");
  183.  
  184. #else
  185. if (thr_join(thread_id[i], NULL, NULL))
  186. printf("Error waiting for thread to terminate\n");
  187. #endif
  188.  
  189. printf("Stop Session %d....",i);
  190. logoff(ctx[i]);
  191. EXEC SQL CONTEXT FREE :ctx[i];
  192. }
  193.  
  194. /*Destroys mutex*/
  195. #ifdef DCE_THREADS
  196. if (pthread_mutex_destroy(&mutex))
  197. #else
  198. if (mutex_destroy(&mutex))
  199. #endif
  200. {
  201. printf("Can't destroy mutex\n");
  202. exit();
  203. }
  204. }
  205.  
  206. /*********************************************************************
  207. * Function: do_transaction
  208. *
  209. * Description: This functions executes one transaction out of the
  210. * records array. The records array is 'managed' by
  211. * the get_transaction function.
  212. *
  213. *
  214. ********************************************************************/
  215. #ifdef DCE_THREADS
  216. void do_transaction(params)
  217. #else
  218. void *do_transaction(params)
  219. #endif
  220. parameters *params;
  221. {
  222. struct sqlca sqlca;
  223. record_log *trx;
  224. sql_context ctx=params->ctx;
  225.  
  226. /* Done all transactions ? */
  227. while (trx_nr < (sizeof(records)/sizeof(record_log)))
  228. {
  229. get_transaction(&trx);
  230.  
  231. EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
  232. EXEC SQL CONTEXT USE :ctx;
  233.  
  234. printf("Thread %d executing transaction\n",params->thread_id);
  235.  
  236. switch(trx->action)
  237. {
  238. case 'M': EXEC SQL UPDATE ACCOUNTS
  239. SET BALANCE=BALANCE+:trx->amount
  240. WHERE ACCOUNT=:trx->to_account;
  241.  
  242. EXEC SQL UPDATE ACCOUNTS
  243. SET BALANCE=BALANCE-:trx->amount
  244. WHERE ACCOUNT=:trx->from_account;
  245. break;
  246. default: break;
  247. }
  248.  
  249. EXEC SQL COMMIT;
  250. }
  251. }
  252.  
  253. /*****************************************************************
  254. * Function: err_report
  255. *
  256. * Description: This routine prints out the most recent error
  257. *
  258. ****************************************************************/
  259. void err_report(sqlca)
  260. struct sqlca sqlca;
  261. {
  262. if (sqlca.sqlcode < )
  263. printf("\n%.*s\n\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
  264. exit();
  265. }
  266.  
  267. /*****************************************************************
  268. * Function: logon
  269. *
  270. * Description: Logs on to the database as USERNAME/PASSWORD
  271. *
  272. *****************************************************************/
  273. void logon(ctx,connect_info)
  274. sql_context ctx;
  275. char * connect_info;
  276. {
  277. EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
  278. EXEC SQL CONTEXT USE :ctx;
  279. EXEC SQL CONNECT :connect_info;
  280. printf("Connected!\n");
  281.  
  282. }
  283.  
  284. /******************************************************************
  285. * Function: logoff
  286. *
  287. * Description: This routine logs off the database
  288. *
  289. ******************************************************************/
  290. void logoff(ctx)
  291. sql_context ctx;
  292. {
  293. EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
  294. EXEC SQL CONTEXT USE :ctx;
  295. EXEC SQL COMMIT WORK RELEASE;
  296. printf("Logged off!\n");
  297. }
  298.  
  299. /******************************************************************
  300. * Function: get_transaction
  301. *
  302. * Description: This routine returns the next transaction to process
  303. *
  304. ******************************************************************/
  305. void get_transaction(trx)
  306. record_log ** trx;
  307. {
  308. #ifdef DCE_THREADS
  309. if (pthread_mutex_lock(&mutex))
  310. #else
  311. if (mutex_lock(&mutex))
  312. #endif
  313. printf("Can't lock mutex\n");
  314.  
  315. *trx = &records[trx_nr];
  316.  
  317. trx_nr++;
  318.  
  319. #ifdef DCE_THREADS
  320. if (pthread_mutex_unlock(&mutex))
  321. #else
  322. if (mutex_unlock(&mutex))
  323. #endif
  324. printf("Can't unlock mutex\n");
  325. }

[作者 高健@博客园  luckyjackgao@gmail.com]
回到上一级页面:PostgreSQL基础知识与基本操作索引页    回到顶级页面:PostgreSQL索引页磨砺技术珠矶,践行数据之道,追求卓越价值

Oracle的 EXEC SQL CONTEXT学习的更多相关文章

  1. Oracle SQL 基础学习

    oracel sql 基础学习 CREATE TABLE USERINFO ( ID ,) PRIMARY KEY, USERNAME ), USERPWD ), EMAIL ), REDATE DA ...

  2. SQL server学习

    慕课网sql server学习 数据库第一印象:desktop--web server--database server** 几大数据库:sql server.oracle database.DB2. ...

  3. SQL语句学习手册实例版

    SQL语句学习手册实例版 表操作 例1  对于表的教学管理数据库中的表 STUDENTS ,可以定义如下: CREATE  TABLE  STUDENTS (SNO      NUMERIC (6, ...

  4. Oracle中PL/SQL简介、基本语法以及数据类型

    Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控 ...

  5. Oracle DBA常用SQL

    监控SQL 1.监控事例的等待: select event,sum(decode(wait_time,0,0,1)) prev, sum(decode(wait_time,0,1,0)) curr,c ...

  6. SQL server学习(三)T-SQL编程、逻辑控制语句和安全模式

    T-SQL编程 T-SQL编程与C语言类似,只是语法稍有不同而已,总体思想还是没有变化的.多的就不说了,还是从变量开始. 变量也分为全局变量和局部变量,表示方式稍有不同. 局部变量: 局部变量必须以标 ...

  7. 搜索表字段包含某字符串的SQL和监控Oracle数据库的SQL。

    1.第一个SQL 背景:需要找到SQL Server数据库中,包含某个字符串的表,输出表和包含该字符串的列. )='=' --这里填要搜索的字符串 DECLARE @sql NVARCHAR(MAX) ...

  8. 下面为初学者分享一下SQL 数据库学习资料

    一.基础 1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份 ...

  9. Oracle OCI操作UDT相关学习(二)

    沿用 Oracle OCI操作UDT相关学习 一文中定义的类型和表. 1.更改数据 在sqldeveloper 中更新数据, update dxl.cust set addr.street='a11' ...

随机推荐

  1. .NET 2.0 参考源码索引

    http://www.projky.com/dotnet/2.0/Microsoft/CSharp/csharpcodeprovider.cs.htmlhttp://www.projky.com/do ...

  2. 如何使用 Jenkins、GitHub 和 Docker 在 Azure 中的 Linux VM 上创建开发基础结构

    若要将应用程序开发的生成和测试阶段自动化,可以使用持续集成和部署 (CI/CD) 管道. 本教程介绍如何在 Azure VM 上创建 CI/CD 管道,包括如何: 创建 Jenkins VM 安装并配 ...

  3. cent7中kickstart

    一.基本环境 操作系统:CentOS7.4 内核版本:3.10.0-862.11.6.el7.x86_64 二.组件部署 yum安装tftp tftpd-server xinetd http dhcp ...

  4. 手动安装 pygame

    在windows下 用pip 安装pygame,老是失败,下载了 wheel文件,用pip安装还是不行,查了一下资料,可以手动安装: 1.在 http://www.lfd.uci.edu/~gohlk ...

  5. java 解析json字符串

    如果转载我的这篇文章请注明出处,谢谢! 最近工作中,需要解析json格式的字符串,恰好有个例子,感觉不错,拿来分享. 运行这个类需要加载jar包:ezmorph-1.0.6.jar.json-lib- ...

  6. dotnet core入门

    dotnet 命令 C:\Users\yshuangj\Desktop\dotnet>dotnet Usage: dotnet [options]Usage: dotnet [path-to-a ...

  7. 批量删除Redis中的数据

    测试环境上是docker安装的redis,生产上使用的是阿里云Redis服务,需要批量清理生产上的数据. 阿里云提供了BS结构的工具管理Redis,但是不能全选批量删除,只能脚本删除,方法是在测试环境 ...

  8. 【[BJOI2017]魔法咒语】

    矩阵乘法+\(AC\)自动机 是道很不错的题了 首先是前六十分,就是一个\(AC\)自动机上的套路\(dp\),设\(dp[i][j]\)表示匹配出的长度为\(i\)在自动机上位置为\(j\)的方案数 ...

  9. AE-----界面介绍

    AE-----界面介绍 一.大纲leiji 层级: 比如:高楼一层一层的盖起来的.千层蛋糕(一层一层的).地质(一层一层构造的) 图层的特征:有顺序.上面的一层总会覆盖掉下面的一层. AfterEff ...

  10. 【node.js】函数、路由

    Node.js中函数的使用与Javascript类似,一个函数可以作为另一个函数的参数.我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数. function say(word) { ...