【问题标题】:Create procedure to execute query in PostgreSQL创建过程以在 PostgreSQL 中执行查询
【发布时间】:2018-09-07 22:06:29
【问题描述】:

也许这不是新案例,但我对此很感兴趣。这是我用来运行查询的过程,它在 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。

【问题讨论】:

    标签: mysql postgresql stored-procedures plpgsql


    【解决方案1】:

    这种技术被命名为动态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

    【讨论】:

    • 感谢@Pavel Stehule。是的,你是对的,只有一行,它可以在 plpgsql 中使用PERFORM 运行。对于像我这样的数据库编程新手,我将为有用的解释投票。
    【解决方案2】:

    如何在 postgresql 11 中创建存储过程并使用 .net 进行 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);
            }
    
    

    【讨论】:

    • 此示例工作正常.. 并由我自己测试。
    猜你喜欢
    • 2020-12-31
    • 1970-01-01
    • 2015-03-24
    • 2019-10-07
    • 2021-10-21
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多