创建在PostgreSQL中执行查询的过程

时间:2018-03-29 03:54:06

标签: mysql postgresql stored-procedures plpgsql

也许它不是新案例,但我会对它进行叠加。这是我用来运行查询的过程,它在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

问题:

  1. 如何将其转换为PostgreSQL版本?
  2. 当我在另一个程序中需要时,如何调用此过程(runstatement)?在MySQL中,我知道为CALL runstatement(param)

    感谢您的回复。我是数据库编程的新手,尤其是PostgreSQL。

2 个答案:

答案 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);
        }