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

Create procedure to execute query in PostgreSQL

也许这不是新案例,但我对此有所了解。这是我用来 运行 查询的过程,它 运行 通常在 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. 当我在另一个程序中需要它时,如何调用这个程序(运行语句)?在 MySQL 我知道是 CALL runstatement(param).

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

此技术名为 动态 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

如何使用 .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$;

以下程序基于 select 查询。

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