Delphi使用AdoQuery調用Mysql存儲過程

  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;

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章