Oracle的 EXEC SQL CONTEXT学习
磨砺技术珠矶,践行数据之道,追求卓越价值
回到上一级页面: 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
- EXEC SQL ENABLE THREADS;
- EXEC SQL CONTEXT ALLOCATE :context_var;
- EXEC SQL CONTEXT USE { :context_var | DEFAULT};
- 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官方例子如下:
- /*
- * Name: Thread_example1.pc
- *
- * Description: This program illustrates how to use threading in
- * conjunction with precompilers. The program creates as many
- * sessions as there are threads. Each thread executes zero or
- * more transactions, that are specified in a transient
- * structure called 'records'.
- * Requirements:
- * The program requires a table 'ACCOUNTS' to be in the schema
- * scott/tiger. The description of ACCOUNTS is:
- * SQL> desc accounts
- * Name Null? Type
- * ------------------------------- ------- ------
- * ACCOUNT NUMBER(36)
- * BALANCE NUMBER(36,2)
- *
- * For proper execution, the table should be filled with the accounts
- * 10001 to 10008.
- *
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sqlca.h>
- #define _EXC_OS_ _EXC__UNIX
- #define _CMA_OS_ _CMA__UNIX
- #ifdef DCE_THREADS
- #include <pthread.h>
- #else
- #include <thread.h>
- #endif
- /* Function prototypes */
- void err_report();
- #ifdef DCE_THREADS
- void do_transaction();
- #else
- void *do_transaction();
- #endif
- void get_transaction();
- void logon();
- void logoff();
- #define CONNINFO "scott/tiger"
- #define THREADS 3
- struct parameters
- { sql_context * ctx;
- int thread_id;
- };
- typedef struct parameters parameters;
- struct record_log
- {
- char action;
- unsigned int from_account;
- unsigned int to_account;
- float amount;
- };
- typedef struct record_log record_log;
- record_log records[]= { { 'M', , , 12.50 },
- { 'M', , , 25.00 },
- { 'M', , , 123.00 },
- { 'M', , , 125.00 },
- { 'M', , , 12.23 },
- { 'M', , , 225.23 },
- { 'M', , , 0.70 },
- { 'M', , , 11.30 },
- { 'M', , , 47.50 },
- { 'M', , , 125.00 },
- { 'M', , , 225.00 },
- { 'M', , , 0.70 },
- { 'M', , , 11.00 },
- { 'M', , , 47.50 },
- { 'M', , , 125.00 },
- { 'M', , , 225.00 },
- { 'M', , , 0.70 },
- { 'M', , , 11.00 },
- { 'M', , , 47.50 },
- { 'M', , , 1034.54}};
- static unsigned int trx_nr=;
- #ifdef DCE_THREADS
- pthread_mutex_t mutex;
- #else
- mutex_t mutex;
- #endif
- /*********************************************************************
- * Main
- ********************************************************************/
- main()
- {
- sql_context ctx[THREADS];
- #ifdef DCE_THREADS
- pthread_t thread_id[THREADS];
- pthread_addr_t status;
- #else
- thread_t thread_id[THREADS];
- int status;
- #endif
- parameters params[THREADS];
- int i;
- EXEC SQL ENABLE THREADS;
- EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
- /* Create THREADS sessions by connecting THREADS times */
- for(i=;i<THREADS;i++)
- {
- printf("Start Session %d....",i);
- EXEC SQL CONTEXT ALLOCATE :ctx[i];
- logon(ctx[i],CONNINFO);
- }
- /*Create mutex for transaction retrieval */
- #ifdef DCE_THREADS
- if (pthread_mutex_init(&mutex,pthread_mutexattr_default))
- #else
- if (mutex_init(&mutex, USYNC_THREAD, NULL))
- #endif
- {
- printf("Can't initialize mutex\n");
- exit();
- }
- /*Spawn threads*/
- for(i=;i<THREADS;i++)
- {
- params[i].ctx=ctx[i];
- params[i].thread_id=i;
- printf("Thread %d... ",i);
- #ifdef DCE_THREADS
- if (pthread_create(&thread_id[i],pthread_attr_default,
- (pthread_startroutine_t)do_transaction,
- (pthread_addr_t) ¶ms[i]))
- #else
- if (status = thr_create
- (NULL, , do_transaction, ¶ms[i], , &thread_id[i]))
- #endif
- printf("Cant create thread %d\n",i);
- else
- printf("Created\n");
- }
- /* Logoff sessions....*/
- for(i=;i<THREADS;i++)
- {
- /*wait for thread to end */
- printf("Thread %d ....",i);
- #ifdef DCE_THREADS
- if (pthread_join(thread_id[i],&status))
- printf("Error when waiting for thread % to terminate\n", i);
- else
- printf("stopped\n");
- printf("Detach thread...");
- if (pthread_detach(&thread_id[i]))
- printf("Error detaching thread! \n");
- else
- printf("Detached!\n");
- #else
- if (thr_join(thread_id[i], NULL, NULL))
- printf("Error waiting for thread to terminate\n");
- #endif
- printf("Stop Session %d....",i);
- logoff(ctx[i]);
- EXEC SQL CONTEXT FREE :ctx[i];
- }
- /*Destroys mutex*/
- #ifdef DCE_THREADS
- if (pthread_mutex_destroy(&mutex))
- #else
- if (mutex_destroy(&mutex))
- #endif
- {
- printf("Can't destroy mutex\n");
- exit();
- }
- }
- /*********************************************************************
- * Function: do_transaction
- *
- * Description: This functions executes one transaction out of the
- * records array. The records array is 'managed' by
- * the get_transaction function.
- *
- *
- ********************************************************************/
- #ifdef DCE_THREADS
- void do_transaction(params)
- #else
- void *do_transaction(params)
- #endif
- parameters *params;
- {
- struct sqlca sqlca;
- record_log *trx;
- sql_context ctx=params->ctx;
- /* Done all transactions ? */
- while (trx_nr < (sizeof(records)/sizeof(record_log)))
- {
- get_transaction(&trx);
- EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
- EXEC SQL CONTEXT USE :ctx;
- printf("Thread %d executing transaction\n",params->thread_id);
- switch(trx->action)
- {
- case 'M': EXEC SQL UPDATE ACCOUNTS
- SET BALANCE=BALANCE+:trx->amount
- WHERE ACCOUNT=:trx->to_account;
- EXEC SQL UPDATE ACCOUNTS
- SET BALANCE=BALANCE-:trx->amount
- WHERE ACCOUNT=:trx->from_account;
- break;
- default: break;
- }
- EXEC SQL COMMIT;
- }
- }
- /*****************************************************************
- * Function: err_report
- *
- * Description: This routine prints out the most recent error
- *
- ****************************************************************/
- void err_report(sqlca)
- struct sqlca sqlca;
- {
- if (sqlca.sqlcode < )
- printf("\n%.*s\n\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
- exit();
- }
- /*****************************************************************
- * Function: logon
- *
- * Description: Logs on to the database as USERNAME/PASSWORD
- *
- *****************************************************************/
- void logon(ctx,connect_info)
- sql_context ctx;
- char * connect_info;
- {
- EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
- EXEC SQL CONTEXT USE :ctx;
- EXEC SQL CONNECT :connect_info;
- printf("Connected!\n");
- }
- /******************************************************************
- * Function: logoff
- *
- * Description: This routine logs off the database
- *
- ******************************************************************/
- void logoff(ctx)
- sql_context ctx;
- {
- EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
- EXEC SQL CONTEXT USE :ctx;
- EXEC SQL COMMIT WORK RELEASE;
- printf("Logged off!\n");
- }
- /******************************************************************
- * Function: get_transaction
- *
- * Description: This routine returns the next transaction to process
- *
- ******************************************************************/
- void get_transaction(trx)
- record_log ** trx;
- {
- #ifdef DCE_THREADS
- if (pthread_mutex_lock(&mutex))
- #else
- if (mutex_lock(&mutex))
- #endif
- printf("Can't lock mutex\n");
- *trx = &records[trx_nr];
- trx_nr++;
- #ifdef DCE_THREADS
- if (pthread_mutex_unlock(&mutex))
- #else
- if (mutex_unlock(&mutex))
- #endif
- printf("Can't unlock mutex\n");
- }
[作者 高健@博客园 luckyjackgao@gmail.com]
回到上一级页面:PostgreSQL基础知识与基本操作索引页 回到顶级页面:PostgreSQL索引页磨砺技术珠矶,践行数据之道,追求卓越价值
Oracle的 EXEC SQL CONTEXT学习的更多相关文章
- Oracle SQL 基础学习
oracel sql 基础学习 CREATE TABLE USERINFO ( ID ,) PRIMARY KEY, USERNAME ), USERPWD ), EMAIL ), REDATE DA ...
- SQL server学习
慕课网sql server学习 数据库第一印象:desktop--web server--database server** 几大数据库:sql server.oracle database.DB2. ...
- SQL语句学习手册实例版
SQL语句学习手册实例版 表操作 例1 对于表的教学管理数据库中的表 STUDENTS ,可以定义如下: CREATE TABLE STUDENTS (SNO NUMERIC (6, ...
- Oracle中PL/SQL简介、基本语法以及数据类型
Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控 ...
- Oracle DBA常用SQL
监控SQL 1.监控事例的等待: select event,sum(decode(wait_time,0,0,1)) prev, sum(decode(wait_time,0,1,0)) curr,c ...
- SQL server学习(三)T-SQL编程、逻辑控制语句和安全模式
T-SQL编程 T-SQL编程与C语言类似,只是语法稍有不同而已,总体思想还是没有变化的.多的就不说了,还是从变量开始. 变量也分为全局变量和局部变量,表示方式稍有不同. 局部变量: 局部变量必须以标 ...
- 搜索表字段包含某字符串的SQL和监控Oracle数据库的SQL。
1.第一个SQL 背景:需要找到SQL Server数据库中,包含某个字符串的表,输出表和包含该字符串的列. )='=' --这里填要搜索的字符串 DECLARE @sql NVARCHAR(MAX) ...
- 下面为初学者分享一下SQL 数据库学习资料
一.基础 1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份 ...
- Oracle OCI操作UDT相关学习(二)
沿用 Oracle OCI操作UDT相关学习 一文中定义的类型和表. 1.更改数据 在sqldeveloper 中更新数据, update dxl.cust set addr.street='a11' ...
随机推荐
- .NET 2.0 参考源码索引
http://www.projky.com/dotnet/2.0/Microsoft/CSharp/csharpcodeprovider.cs.htmlhttp://www.projky.com/do ...
- 如何使用 Jenkins、GitHub 和 Docker 在 Azure 中的 Linux VM 上创建开发基础结构
若要将应用程序开发的生成和测试阶段自动化,可以使用持续集成和部署 (CI/CD) 管道. 本教程介绍如何在 Azure VM 上创建 CI/CD 管道,包括如何: 创建 Jenkins VM 安装并配 ...
- cent7中kickstart
一.基本环境 操作系统:CentOS7.4 内核版本:3.10.0-862.11.6.el7.x86_64 二.组件部署 yum安装tftp tftpd-server xinetd http dhcp ...
- 手动安装 pygame
在windows下 用pip 安装pygame,老是失败,下载了 wheel文件,用pip安装还是不行,查了一下资料,可以手动安装: 1.在 http://www.lfd.uci.edu/~gohlk ...
- java 解析json字符串
如果转载我的这篇文章请注明出处,谢谢! 最近工作中,需要解析json格式的字符串,恰好有个例子,感觉不错,拿来分享. 运行这个类需要加载jar包:ezmorph-1.0.6.jar.json-lib- ...
- dotnet core入门
dotnet 命令 C:\Users\yshuangj\Desktop\dotnet>dotnet Usage: dotnet [options]Usage: dotnet [path-to-a ...
- 批量删除Redis中的数据
测试环境上是docker安装的redis,生产上使用的是阿里云Redis服务,需要批量清理生产上的数据. 阿里云提供了BS结构的工具管理Redis,但是不能全选批量删除,只能脚本删除,方法是在测试环境 ...
- 【[BJOI2017]魔法咒语】
矩阵乘法+\(AC\)自动机 是道很不错的题了 首先是前六十分,就是一个\(AC\)自动机上的套路\(dp\),设\(dp[i][j]\)表示匹配出的长度为\(i\)在自动机上位置为\(j\)的方案数 ...
- AE-----界面介绍
AE-----界面介绍 一.大纲leiji 层级: 比如:高楼一层一层的盖起来的.千层蛋糕(一层一层的).地质(一层一层构造的) 图层的特征:有顺序.上面的一层总会覆盖掉下面的一层. AfterEff ...
- 【node.js】函数、路由
Node.js中函数的使用与Javascript类似,一个函数可以作为另一个函数的参数.我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数. function say(word) { ...