C# + 微软企业库(Microsoft.Enterprise.Library),实现Oracle字段自增的应用

来源:互联网 发布:找小项目源码去哪儿? 编辑:程序博客网 时间:2024/05/17 00:52

在数据库设计中,常常需要一个唯一表示数据记录的字段,我们叫“标识字段”,这个字段往往用于表记录之间的关联,对于SQL Server的使用者来说,只要把一个int型字段设置成“自增”就可以了。但是Oracle没有“自增”字段,这篇文章谈谈Oracle实现字段自增长并用C#调用微软企业库来访问的运用。

.建表

建立一个测试用的表Test结构如下

列名

类型

是否可为空

说明

ID

NUMBER

N

实现自增字段

A

NUMBER

Y

测试字段1

B

VARCHAR2(50)

Y

测试字段2

接下来我们要实现列ID的自增,并用企业库调用。

二.建立序列

建立一个名称为Test_SQL的序列,使用PL/SQL查看序列的属性如下:

SEQUENCE_OWNER

ZHYUANSAN

SEQUENCE_NAME

TEST_SQL

MIN_VALUE

1

MAX_VALUE

1E27

INCREMENT_BY

1

CYCLE_FLAG

N

ORDER_FLAG

N

CACHE_SIZE

20

三.建立触发器

建立触发器代码如下:

create or replace trigger Test_INSERT_trigger

before insert on Test

for each row

begin

select Test_SQL.nextval into :new.ID from dual;

end ;

四.使用企业库插入数据

这时,我们可以使用PL/SQL插入数据:

insert into test values(0,23,’bbb’);

这里虽然第一个字段插入的数据是0,但是触发器自动会给它赋自增字段的值。

1.企业库配置文件

使用微软的企业库,连接数据库配置文件这样写:

  <configSections>

    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data,Version= 2.0.0.0,Culture=neutral,PublicKeyToken=null"/>

  </configSections>

  <dataConfiguration defaultDatabase= "ORACLE"/>

  <connectionStrings>

    <add name="ORACLE" connectionString="Data Source=gis;User ID=ZHYUANSHAN;Password=123456;Unicode=True" providerName= "System.Data.OracleClient"/>

  </connectionStrings>

2.创建数据库访问对象

public static Database db = DatabaseFactory.CreateDatabase();

3.插入记录代码

string strsql = "INSERT INTO TEST(0,:A,:B) ";

DbCommand cmd = db. GetSqlStringCommand(strsql);

db. AddInParameter (cmd, "A", DbType.Int32, 23);

db. AddInParameter (cmd, "B", DbType.String, ddd);

db.ExecuteNonQuery(cmd);

五.问题

上面已经实现了数据的插入,也实现了字段自增,但是还有个问题就是,当有两个表关联时,我希望插入一个表的数据后,能够返回自增字段的值,然后再把这个值插入到另外一个表,实现两个表的关联。

如何返回这个新插入的自增字段的值呢?

有人说直接再写一行代码执行SELECT Test_SQL.currval from dual来获取自增字段的值不就可以了吗?

实际这样调用是不行的,SELECT Test_SQL.currval from dual只能在使用currval.nextval的同一个会话中调用,否则会出现“序列(号)不存在”的错误。

六.实现返回自增标识字段值

要马上获取自增标识字段的值,有以下3中方法:

1.先取值再插入(不需要触发器)

先执行命令SELECT Test_SQL.nextval from dual,来获取标识的值,再把这个值作为参数插入到数据库。这样就不需要触发器了,但是导致编码变得复杂,要增加获取标识的代码,插入时也要多传一个参数。

获取标识字段值代码:


 

string strsql = "SELECT Test_SQL.nextval FROM dual";

DbCommand cmd = db. GetSqlStringCommand(strsql);

object ob = db. ExecuteScalar(cmd);

int id = Convert.ToInt32(ob);

插入记录代码

strsql = "INSERT INTO TEST(:ID,:A,:B) ";

cmd = db. GetSqlStringCommand(strsql);

db.AddInParameter(cmd, "ID", DbType.Int32, id);

db.AddInParameter(cmd, "A", DbType.Int32, 23);

db.AddInParameter(cmd, "B", DbType.String, ddd);

db.ExecuteNonQuery(cmd);

……继续插入关联表信息。

2.利用存储过程(不需要触发器)

我们可以把上面的逻辑放到存储过程中,虽然我们增加了存储过程的编写,但是外部调用方法就更接近SQL Server了。

存储过程代码:

CREATE OR REPLACE PROCEDURE InsertTest(A in number,B in nvarchar2,id out  number)
as
BEGIN
SELECT test_seq.nextval into id from dual;
insert into test values(id,A,B);
END InsertTest;

外部调用代码:

int id = 0;

string strsql = "InsertTest";

DbCommand cmd = db.GetStoredProcCommand(strsql);

db.AddInParameter(cmd, "A", DbType.Int32, 23);

db.AddInParameter(cmd, "B", DbType.String, ddd);

db.AddOutParameter(cmd, "id", DbType.Int32, id);

db.ExecuteNonQuery(cmd);

id = Convert.ToInt32(db.GetParameterValue(cmd, "id"));

……继续插入关联表信息。

3.利用存储过程 + 触发器

我们可以利用触发器,这样插入的时候就不用传入id了。

触发器代码:

create or replace trigger Test_INSERT_trigger

before insert on Test

for each row

begin

select Test_SEQ.nextval into :new.ID from dual;

end ;

存储过程代码:

CREATE OR REPLACE PROCEDURE InsertTest (A in number,B in nvarchar2,id out  number)
as
BEGIN
insert into test values(
0,A,B);
SELECT test_seq.currval into id from dual;
END InsertTest;

外部调用代码:

int id = 0;

string strsql = "InsertTest";

DbCommand cmd = db.GetStoredProcCommand(strsql);

db.AddInParameter(cmd, "A", DbType.Int32, 23);

db.AddInParameter(cmd, "B", DbType.String, ddd);

db.AddOutParameter(cmd, "id", DbType.Int32, id);

db.ExecuteNonQuery(cmd);

id = Convert.ToInt32(db.GetParameterValue(cmd, "id"));

……继续插入关联表信息。

原创粉丝点击