经过前面的了解,现在想用C语言来编程了,搜索了很多东西,后来决定先用Pro C来进行学习

在安装完Oracle数据库后就可以进行编程了,里面有一个命令proc就是对程序进行预编译的。

在这记一下,这是一个学习PL/SQL的网站,挺好的

http://www.cnblogs.com/huyong/archive/2012/07/30/2614563.html

创建用户是

create user xx identified by xx account unlock;

grant connect, resource to xx;

第一句是创建用户xx,并且密码是xx,并且解锁用户

下面那句是给用户连接权限和一般操作自己用户下的表的权限等。

写一个test.pc然后

proc iname=test.pc oname=test.c

但是我这怎么也不行,一直出问题

后来我用

proc PARSE=NONE CODE=KR_C LINE=YES INAME=test.pc MODE=ORACLE DBMS=V8 UNSAFE_NULL=YES

后来补充:之后我大概看了一下这些编译指令,我得记录一下:

1. UNSAFE_NULL=YES    这是避免这个错误:3.6.121405 错误(Fetch column values is null)

也就是允许应用程序从数据库中检索出NULL到宿主变量而不产生错误。

2. CODE=KR_C  这是指代码风格吧,可以是CPP、ANSI_C、KR_C

其中ANSI_C和KR_C都是C语言风格,CPP是C++的

3. 命令行参数MAXLITERAL 指定了其预编译成C/C++语言源
文件时所转换的最长单行代码长度,默认为1024 字

4. 在Pro*C/C++预编译器的参数中如果AUTO_CONNECT=true,则可以在源程序中
不显视的连接数据库  ------- 书里是这么说的,但是我没有连接成功,应该是设置有问题,等着以后解决。

5. 如果在一个应用程序中,需要同时使用大量游标,应该调整 proc 命令行参数
MAXOPENCURSORS

6. CLOSE_ON_COMMIT 预编译选项决定了是否在COMMIT 语句时自动关闭事务中的游
标,当MODE=ansi 时,CLOSE_ON_COMMIT 默认为yes。明确的指定CLOSE_ON_COMMIT
为no,则COMMIT 时不关闭游标,游标不需要重新打开,可以提升应用程序性能

这下才生成了test.c文件

之后用gcc编译

gcc test.c -L${ORACLE_HOME}/lib -lclntsh -lecpg

这里我明明把-L的路径配置了,但是为什么还是要在这里写上呢

遇到的问题还需要进一步处理。

1. test.pc

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *userid="scott"; 
char *passwd="xx";
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :userid IDENTIFIED BY :passwd;
    if (sqlca.sqlcode == 0) {
        printf("ok\n");
    } else {
        printf("false\n");
        exit(1);
    }
    EXEC SQL SELECT * FROM EMP;
    return 0;
}

这里的变量声明在

EXEC SQL BEGIN DECLARE SECTION;

...在这里

EXEC SQL END DECLARE SECTION;

执行SQL语句前面用EXEC SQL

执行PL/SQL前面用

EXEC SQL EXECUTE  开始

END-EXEC  结束

如果要根据条件进行预编译,就像c中的#ifdef这样的

EXEC ORACLE DEFINE xx;

EXEC ORACLE IFDEF xx;

EXEC ORACLE IFNDEF xx;

EXEC ORACLE ELSE;

EXEC ORACLE ENDIF;

并且这个定义可以在proc预处理时加上:proc 命令行加入参数DEFINE=xx

在里面还有一个指示变量概念,INDICATOR 表示,下面是指示变量相应值代表的含义。

0 操作成功
-1 该指示变量对应的宿主变量返回了或插入、更新成了NULL 值
-2 从数据库存放数据到对应的宿主变量时,数据超长,并且不能推断出截断了多
少字节的长度
>0 在FETHC 或SELECT 语句时,因数据超长而被截断存放在了对应的宿主变量
中,指示变量存放对应列的长度

这里我还用了select这句,要怎么显示结果呢?

经过了一会的琢磨,看了看相关文章,总算是弄出个差不多的了,直接贴上代码来看看。

2. connect.pc

#include <stdio.h> 
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char name[14][10];
int sal[14];
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    int i;
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    EXEC SQL SELECT ename, sal INTO :name, :sal
        FROM EMP;
    for (i = 0; i < 14; i ++) {
        printf("%s\t%d\n", name[i], sal[i]);
    }
    return 0;
}

我定义的变量name是一个二维数组,每个都是10的大小,这个和表emp中ename的是一致的,这样才可以用来接收ename

的值,类型必须保存一致。

用INTO把相应的值弄入相应变量,然后打印输出。

这里我还没有解决那个proc编译选项的问题,还是需要那个长的那么来编译。

3. insert.pc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
int emp_number;
char emp_name[10];
int emp_sal;
int dept_number;
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    strcpy(emp_name, "bxx");
    int emp_number = 8888;
    int emp_sal = 8888;
    int dept_number = 40;
    EXEC SQL INSERT INTO EMP (empno, ename, sal, deptno)
        VALUES (:emp_number, :emp_name, :emp_sal, :dept_number);
    EXEC SQL COMMIT WORK RELEASE; 
    return 0;
}

这里是调用 INSERT来写入数据,并且写入后要COMMIT,这样数据库才有变化。

其实因为我SQL语句也是刚学一两天,这个更是今天才开始学习,所以,我每一个命令就建一个.pc文件来练习,

熟能生巧,现在不求巧,只求先用熟。

4. update.pc

#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char *emp_job = "MANAGER";
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    EXEC SQL UPDATE emp SET job=:emp_job
        WHERE ename='bxx';
    EXEC SQL COMMIT WORK RELEASE;
    return 0;
}

5. delete.pc

#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char *emp_name = "bxx";
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    if (sqlca.sqlcode == 0) {
        printf("Connected to user: %s\n", username);
    } else {
        printf("Connect to user %s failed\n", username);
        exit(1);
    }
    EXEC SQL DELETE FROM emp
        WHERE ename=:emp_name;
    EXEC SQL COMMIT WORK RELEASE;
    return 0;
}

6. 下面是游标的,上面用过一次二维数组,如果用游标就不用二维数组了

cursor.pc

#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char emp_name[10];
int sal;
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    EXEC SQL DECLARE emp_cursor CURSOR FOR
        SELECT ename, sal
        FROM emp;
    EXEC SQL OPEN emp_cursor;
    int i;
    for (i = 0; i < 14; i ++) {
        EXEC SQL FETCH emp_cursor
            INTO :emp_name, :sal;
        printf("%s\t%d\n", emp_name, sal);
    }
    EXEC SQL CLOSE emp_cursor;
    return 0;
}

原本我没有用for里面记14次的,而是用的while(1),

然后用了那个NOT FOUND,但是怎么就不行呢,一直循环下去了。也用了if (sqlca.sqlcode == 1403)

都是无限循环,根本停不下来,还需要进一步学习,怎么用这块,错误的代码我也贴一下。

问题算是解决了一半,可以跳出来了,原因是:那个头文件#inclucde <sqlca.h>,我把它改成

EXEC SQL INCLUDE sqlca

用这样的就可以结束循环了,并且那个sqlca.sqlcode也是1403了。

但是关键是这个到底是怎么回事呢?我想应该和proc预编译有关,那个PARSE=NONE,但是如果改成别的,

一直编译不过去。新人就是会遇到各种问题。

#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char emp_name[10];
int sal;
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    EXEC SQL DECLARE emp_cursor CURSOR FOR
        SELECT ename, sal
        FROM emp;
    EXEC SQL OPEN emp_cursor;
    EXEC SQL WHENEVER NOT FOUND GOTO zheli;
    int i;
    while (1) {
        EXEC SQL FETCH emp_cursor
            INTO :emp_name, :sal;
        if (sqlca.sqlcode == 1403)
            break;
        printf("%s\t%d\n", emp_name, sal);
    }
zheli:
    EXEC SQL CLOSE emp_cursor;
    return 0;
}

两种我都用上了,就是不行,还是无限循环。下面有一个例子用的是break,这个我也用过了就是不行

#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
char *username = "scott";
char *passwd = "xx";
char emp_name[10];
int sal;
EXEC SQL END DECLARE SECTION;
int main(int argc, char *argv[])
{
    EXEC SQL CONNECT :username IDENTIFIED BY :passwd;
    EXEC SQL DECLARE emp_cursor CURSOR FOR
        SELECT ename, sal
        FROM emp;
    EXEC SQL OPEN emp_cursor;
    EXEC SQL WHENEVER NOT FOUND DO break;
    int i;
    while (1) {
        EXEC SQL FETCH emp_cursor
            INTO :emp_name, :sal;
        printf("%s\t%d\n", emp_name, sal);
    }
    EXEC SQL CLOSE emp_cursor;
    return 0;
}

原文地址:http://my.oschina.net/bxxfighting/blog/383247

[转]Oracle学习记录 九 Prc C学习的更多相关文章

  1. zeromq学习记录(九)练习代码学习ZMQ_ROUTER ZMQ_READLER

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  2. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...

  3. WebGPU学习(九):学习“fractalCube”示例

    大家好,本文学习Chrome->webgpu-samplers->fractalCube示例. 上一篇博文: WebGPU学习(八):学习"texturedCube"示 ...

  4. 深度学习(九) 深度学习最全优化方法总结比较(SGD,Momentum,Nesterov Momentum,Adagrad,Adadelta,RMSprop,Adam)

    前言 这里讨论的优化问题指的是,给定目标函数f(x),我们需要找到一组参数x(权重),使得f(x)的值最小. 本文以下内容假设读者已经了解机器学习基本知识,和梯度下降的原理. SGD SGD指stoc ...

  5. GUI学习之九——QLineEdit的学习总结

    我们在前面学习了各种按钮控件,从这一章开始就是各种输入控件的学习. 首先要用的就是QLineEdit——单行编辑器, 一描述 QLineEdit是一个单行文本编辑器,允许用户输入和编辑单行纯文本.自带 ...

  6. Ansible学习记录五:PlayBook学习

    0.介绍 Playbooks 是 Ansible 管理配置.部署应用和编排的语言,可以使用 Playbooks 来描述你想在远程主机执行的策略或者执行的一组步骤过程等 类似于一组任务集,定义好像项目, ...

  7. r-cnn学习(九):学习总结

    首先看下代码文件夹的说明(这部分转自:http://blog.csdn.net/bailufeiyan/article/details/50749694) tools 在tools文件夹中,是我们直接 ...

  8. webrtc学习———记录二:canvas学习

    参考资料: http://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html#getcontext2d https://developer.m ...

  9. Java 8 学习记录

    Java 8 学习记录 官方文档 https://docs.oracle.com/javase/8/ https://docs.oracle.com/javase/8/docs/index.html ...

随机推荐

  1. 【JEMTER】后置处理器JSON Path Extractor获取server端返回的json中某项值

    需求1:点击所有报表模板时,server端返回所有报表模板的ID(templateId),测试时需要下载某个模板生成的报表 需求2:点击单个报表模板时,server端返回这个报表模板下的所有报表ID( ...

  2. Java优先级队列

    package com.lk.A; import java.util.PriorityQueue; public class Test5 { public static void main(Strin ...

  3. iOS 设计模式之单例

    设计模式:单例 一.  单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并 ...

  4. (五)u-boot2013.01.01 for TQ210:《移植前的准备及u-boot初编译》

    移植前的准备 移植前,要做的事情是搭建开发环境以及对U-boot源码的获取.首先说一下开发环境: 1.此次U-boot移植的硬件平台是天嵌的TQ210开发板: CPU:板载核心是S5PV210(Cor ...

  5. Lnmp下安装memcached

            Lnmp下安装memcached 1.先安装 libevent,再安装 Memcached主程序 # tar xf libevent-2.0.21-stable.tar.gz # cd ...

  6. 转:从三层架构到MVC-MVP

    当然这种架构模式本身的一些问题也会在接下来的内容就加以介绍,另外就是如果大家有什么不同观点的话,欢迎拍砖(只要不打脸就行,呵呵). 一. MVC是谁提出的 模型-视图-控制器(MVC)是Xerox P ...

  7. [__NSCFNumber length]: unrecognized selector sent to instance 0x8b3c310

    出现这种问题一般是你把int类型的数值赋给了NSString. 比如: 你定义了一个NSString类型的属性sex,但是服务端返回的sex字段实际上是NSNumber类型, 你直接把NSNumber ...

  8. .NET DLL 保护措施详解(三)最终效果

    针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...

  9. ASP.NET不拖控件教程(1)-认识JSON

    我讲讲脱离ASP.NET控件必备的一步,JSON和使用JQuery获取JSON吧! 高手跳过,写给学习中的人的.这篇帖子是假设你会使用JQuery(JQ这么普及,应该不至少没学过吧!真没学过以后再开帖 ...

  10. 收集一下Windows7系统啊

    Windows7系统:http://down.662p.com/list/141_1.html   萝卜家园WIN7系统X86位旗舰特别GHOST版2014年12月 这个是萝卜家园WIN7系统X86位 ...