MFC中和libpq调用PostgreSQL存储过程需要注意的问题

1、 用MFC以ADO方式连接PostgreSQL数据库,调用PostgreSQL数据库的存储过程。简略代码为:

_ConnectionPtr pconnection = theApp.getdbconnection();

_RecordsetPtr pPtr;
if (FAILED( pPtr.CreateInstance( __uuidof(Recordset) )))
{
  return -5;
}

CString strSQL;
strSQL.Format( _T("select * from /"funCheckLogin/"( '%s', '%s' )"), m_szLoginName, m_szLoginPwd );

_variant_t varSQL(strSQL);
HRESULT hr = S_FALSE;
try
{
  hr = pPtr->Open( varSQL,_variant_t((IDispatch*)pconnection,true),adOpenStatic,adLockOptimistic,adCmdText);
}

其中存储过程"funCheckLogin"返回的是记录集SETOF形式,用该种方式调用存储过程时,结果都正常,只是在PostgreSQL的Log中会有

2008-08-05 16:29:46 HKT ERROR:  relation "funCheckLogin" does not exist
2008-08-05 16:29:46 HKT STATEMENT:  select nspname from pg_namespace n, pg_class c where c.relnamespace=n.oid and c.oid='"funCheckLogin"'::regclass

这样的Error错误显示,虽然不影响正常使用,但毕竟有错误发生。

若"funCheckLogin"返回一列一行的形式,比如返回int或varchar等等,调用时使用

strSQL.Format( _T("select  /"funCheckLogin/"( '%s', '%s' )"), m_szLoginName, m_szLoginPwd );

hr = pPtr->Open( varSQL,_variant_t((IDispatch*)pconnection,true),adOpenStatic,adLockOptimistic,adCmdText);

这样也没有LOG错误,究其原因是,select * from后在PostgreSQL中是以查询表的方式存在,而数据库中并没有"funCheckLogin"这个表,因此会出现Error。改正方式如下:

(1)若在pgAdmin中可以用select  /"funCheckLogin/"( '%s', '%s' )的形式,则

strSQL.Format( _T("select  /"funCheckLogin/"( '%s', '%s' )"), m_szLoginName, m_szLoginPwd );

hr = pPtr->Open( varSQL,_variant_t((IDispatch*)pconnection,true),adOpenStatic,adLockOptimistic,adCmdText);

可以正常使用。

(2)若在pgAdmin中必须用select * from存储过程的形式(如返回SETOF),则可以修改VC中的调用方式:

strSQL.Format( _T(" /"funCheckLogin/"( '%s', '%s' )"), m_szLoginName, m_szLoginPwd );

hr = pPtr->Open( varSQL,_variant_t((IDispatch*)pconnection,true),adOpenStatic,adLockOptimistic,adCmdStoreProc);

其实方式(2)才是调用存储过程比较合理的方式。

 

2、Linux下在Libpq中调用PostgreSQL的存储过程,若存储过程返回游标的形式,比如:

CREATE OR REPLACE FUNCTION "funSelectScenarioElementBySid"(REFCURSOR,Sid INT)
RETURNS REFCURSOR AS
$$
BEGIN
OPEN $1 FOR
SELECT "SEid","SEindex","SEcontent","SEsynthesis","SEdlgelement","SEbranchCondition","SErepeatedly","SEtbname","SEfieldname","SEtargetname"
FROM
 "ScenarioElement"
WHERE
 "Sid" = Sid
ORDER BY "SEid";
RETURN $1;
END
$$
LANGUAGE PLPGSQL;

--BEGIN
--SELECT "funSelectScenarioElementBySid"('A',2)
--FETCH ALL IN "A"
--END

在该种形式下,在libpg中是不需要执行

res = PQexec(conn, "CLOSE myportal");
PQclear(res);

否则,会在数据库服务器的LOG中写入错误,如下:

ERROR:  34000: cursor "recordcur" does not exist
LOCATION:  PerformPortalClose, portalcmds.c:236
STATEMENT:  CLOSE recordcur。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值