Delphi使用AdoQuery调用Mysql存储过程

来源:互联网 发布:激战2优化 编辑:程序博客网 时间:2024/05/14 21:37

 Delphi一般使用TADOStoredProc来访问存储过程,TADOStoredProc与TADOQuery都是继承自TCustomADODataSet类,实际上使用TADOQuery来访问存储过程会更灵活一点。

 

现将使用TADOQuery访问存储过程总结一下:

 

1. 执行存储过程,不返回结果结合


存储过程脚本:

DELIMITER $$

 

DROP PROCEDURE IF EXISTS p_test1;

CREATE PROCEDURE p_test1(

iSqn: INT,

sName: VARCHAR(40))

BEGIN

insert into t1(sqn, name) value(iSqn, sName);      

END$$

 

DELIMITER ;

 

 

执行存储过程代码:

function Exec_Proc1: Boolean;

begin

result := true;

query.close;

query.sql.clear;

query.sql.add('call p_test1(:sqn, :name)');

query.Parameters[0].value := 1;

query.Parameters[1].value := 'test';

try

query.ExecSql;

except

result := false;

//写日志什么的处理

end;

end;

 

2. 执行存储过程,返回一个结果集,从结果集中获取数据


存储过程脚本:

DELIMITER $$

 

DROP PROCEDURE IF EXISTS p_test2;

CREATE PROCEDURE p_test2(

iSqn: INT,

sName: VARCHAR(40))

BEGIN

select * from t1 where sqn = iSqn and name = sName;

END$$

 

DELIMITER ;

 

 

调用存储过程代码:

function Exec_Proc2: Boolean;

begin

result := true;

query.close;

query.sql.clear;

query.sql.add('call p_test2(:sqn, :name)');

query.Parameters[0].value := 1;

query.Parameters[1].value := 'test';

try

query.open;

while not query.eof do

begin

//读数据

query.next;

end;

except

result := false;

//写日志什么的处理

end;
end; 

 

3. 执行存储过程,返回一个结果集,结果集在grid中显示

设置datasource1.dataset = query;

设置grid的datasource为datasource1

 

存储过程脚本:

DELIMITER $$

 

DROP PROCEDURE IF EXISTS p_test2;

CREATE PROCEDURE p_test2(

iSqn: INT,

sName: VARCHAR(40))

BEGIN

select * from t1 where sqn = iSqn and name = sName;

END$$

 

DELIMITER ;

 

 

调用存储过程代码:

function Exec_Proc2: Boolean;

begin

result := true;

query.close;

query.sql.clear;

query.sql.add('call p_test2(:sqn, :name)');

query.Parameters[0].value := 1;

query.Parameters[1].value := 'test';

try

query.open;

except

result := false;

//写日志什么的处理

end;

 

end; 

 

4. 执行存储过程,返回多个结果集

设置datasource1.dataset = query;

设置grid的datasource为datasource1

 

存储过程脚本:

DELIMITER $$

 

DROP PROCEDURE IF EXISTS p_test2;

CREATE PROCEDURE p_test2(

iSqn: INT,

sName: VARCHAR(40))

BEGIN

select * from t1 where sqn = iSqn and name = sName;

select 20 as defineSqn, 'test' as defineName;

END$$

 

DELIMITER ;

 

调用存储过程代码:

function Exec_Proc4: Boolean;

var

rs: _Recordset;

recordCount: Integer;

sqn: integer;

name: string;

begin

result := true;

query.close;

query.sql.clear;

query.sql.add('call p_test2(:sqn, :name)');

query.Parameters[0].value := 1;

query.Parameters[1].value := 'test';

try

query.open;

 

// 获得第二个结果集中的数据

rs := query.NextRecordset(recordCount);

if rs <> nil then

begin

sqn := rs.Fields[0].value;

name := rs.Field[1].value;

end;

 

// 获得第二个结果集,第二个结果集用于grid显示

// 设置query2与grid的关联关系(通过datasource)

// rs := query.NextRecordset(recordCount);

// query2.recordSet := rs;

except

result := false;

//写日志什么的处理

end;

 

特别的针对下面的情况:

存储过程脚本:

 

DELIMITER $$

 

DROP PROCEDURE IF EXISTS p_test5;

CREATE PROCEDURE p_test5(

iSqn: INT,

sName: VARCHAR(40),

OUT value: VARCHAR(20))

BEGIN

select * from t1 where sqn = iSqn and name = sName;

set value = 'test';

END$$

 

DELIMITER ;

 

 

调用存储过程代码:

function Exec_proc5: Boolean;

var

aValue: string;

begin

query.close;

query.sql.clear;

query.sql.add('call p_test5(:sqn, :name, @p)');

query.Parameters[0].value := 1;

query.Parameters[1].value := 'test';

try

query.open;

except

result := false;

//写日志什么的处理

end;

 

// 通过另外一个TADOQuery类可以通过查询临时变量@p的方式获得返回值

// 这种方式不是很好,并发量比较大的情况下,取@p的值存在问题

// 解决的办法是不使用传出参数,通过传出第二个结果集的形式,取第二个结果集中的数据相对来说比较好一点

query2.close;

query2.sql.clear;

query2.sql.add('select @p as aValue;');

try

query2.open;

aValue := query2.FieldByname('aValue').asString;

except

end;

end;

 

 

原创粉丝点击