也许它不是新案例,但我会对它进行叠加。这是我用来运行查询的过程,它在MySQL中正常运行,但在PostgreSQL中没有,我不知道如何做到这一点。程序(在MySQL中)看起来像:
CREATE PROCEDURE runstatement(IN statement TEXT)
BEGIN
set @s = statement;
IF LENGTH(@s) <> 0 THEN PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END
问题:
当我在另一个程序中需要时,如何调用此过程(runstatement)?在MySQL中,我知道为CALL runstatement(param)
。
感谢您的回复。我是数据库编程的新手,尤其是PostgreSQL。
答案 0 :(得分:3)
此技术名为动态SQL 。对于这种情况,PLpgSQL有EXECUTE
语句。为此专门编写特殊函数可能没用,因为EXECUTE
是一行命令。
CREATE OR REPLACE FUNCTION runstatement(statement TEXT)
RETURNS void AS $$
BEGIN
IF statement <> '' THEN
EXECUTE statement;
END IF;
END;
$$ LANGUAGE plpgsql;
可能在空字符串上测试是不好的设计。不应该这种情况。 Assert
在那里更好。
可以调用此函数:
SELECT runstatement(''); -- outside plpgsql
或
PERFORM runstatement('') -- inside plpgsql
请参阅文档中的related part。
答案 1 :(得分:-1)
如何使用.net在Postgresql 11和dbconnection中创建存储过程。
如果我们使用的是旧版本,则没有程序。现在我们在postgresql版本11中有过程。这是新的postgresql版本11。
-- DROP PROCEDURE public.sp_lite_web_login_conn(text, character varying, xml, xml);
-- call sp_lite_web_login_conn('PG_LOAD', 'LG570', 'one', 'two')
CREATE OR REPLACE PROCEDURE public.sp_lite_web_login_conn(
p_flag text,
p_site character varying,
INOUT result_one refcursor,
INOUT result_two refcursor)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
open result_one FOR SELECT 'NOT_OK' AS STATUS;
open result_two FOR SELECT 'NOT_OK' AS STATUS;
END;
$BODY$;
以下基于refcursor的过程进行选择查询。
public DataSet executeSelectQuery_POST_PROC(string _query, NpgsqlParameter[] sqlParameter)
{
NpgsqlConnection npg_conn1 = new NpgsqlConnection(connstring);
try
{
npg_conn1.Open();
NpgsqlTransaction tran = npg_conn1.BeginTransaction();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
NpgsqlCommand command = new NpgsqlCommand(_query, npg_conn1);
command.CommandType = CommandType.Text;
command.Parameters.AddRange(sqlParameter);
command.ExecuteNonQuery();
NpgsqlDataAdapter da;
int i = 0;
foreach (NpgsqlParameter parm in sqlParameter)
{
if (parm.NpgsqlDbType == NpgsqlTypes.NpgsqlDbType.Refcursor)
{
string parm_val = string.Format("FETCH ALL IN \"{0}\"", parm.Value.ToString());
da = new NpgsqlDataAdapter(parm_val.Trim().ToString(), npg_conn1);
ds.Tables.Add(parm_val);
da.Fill(ds.Tables[i]);
i++;
}
}
tran.Commit();
return ds;
}
catch (Exception ex)
{
return null;
}
finally
{
npg_conn1.Close();
}
}
user control
public DataSet db_validation(string flag, string site)
{
string query = string.Format(@"call sp_lite_web_login_conn('" + flag + "','" + site + "',@first_tbl,@second_tbl)");
NpgsqlParameter[] sqlParameters = new NpgsqlParameter[4];
sqlParameters[0] = new NpgsqlParameter("@p_flag", SqlDbType.VarChar);
sqlParameters[0].Value = Convert.ToString(flag);
sqlParameters[1] = new NpgsqlParameter("@p_site", SqlDbType.VarChar);
sqlParameters[1].Value = Convert.ToString(site);
//
sqlParameters[2] = new NpgsqlParameter("@first_tbl", NpgsqlTypes.NpgsqlDbType.Refcursor);
sqlParameters[2].Value = Convert.ToString("first_tbl");
sqlParameters[2].Direction = ParameterDirection.InputOutput;
sqlParameters[2].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
sqlParameters[3] = new NpgsqlParameter("@second_tbl", NpgsqlTypes.NpgsqlDbType.Refcursor);
sqlParameters[3].Value = Convert.ToString("second_tbl");
sqlParameters[3].Direction = ParameterDirection.InputOutput;
sqlParameters[3].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
return conn.executeSelectQuery_POST_PROC(query, sqlParameters);
}