Create procedure to execute query in PostgreSQL

狂风中的少年 提交于 2019-12-11 14:08:33

问题


Maybe it's not new case, but I'm stack about it. This is the procedure that I use to run query, it run normally in MySQL, but not in PostgreSQL and I don't know how to do that. The procedure(in MySQL) looks like :

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

The questions :

  1. How do I convert it to PostgreSQL version?
  2. How do I call this procedure(runstatement) when I need it in another procedure? In MySQL I know as CALL runstatement(param).

    Thanks for each reply. I'm new in database programming especially PostgreSQL.


回答1:


This technique is named dynamic SQL. PLpgSQL has EXECUTE statement for this case. Probably is useless to write special function just for this, because EXECUTE is one line command.

CREATE OR REPLACE FUNCTION runstatement(statement TEXT)
RETURNS void AS $$
BEGIN
  IF statement <> '' THEN
    EXECUTE statement;
  END IF;
END;
$$ LANGUAGE plpgsql;

Probably test on empty string is bad design. This case should not to be. Assert is better there.

This function can be called:

SELECT runstatement(''); -- outside plpgsql

or

PERFORM runstatement('') -- inside plpgsql

See related part in documentation.




回答2:


how to create stored procedures in postgresql 11 and dbconnection with .net.
if we have older version we don't have procedures. now we have procedures in postgresql version 11. This is new postgresql version 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$;

the below procedures refcursor based select query.

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



来源:https://stackoverflow.com/questions/49547761/create-procedure-to-execute-query-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!