如何让用户在PostgresSQL / plpgsql中输入输入?

时间:2017-02-08 16:54:57

标签: sql database postgresql plpgsql

您好我想从我的用户那里获取输入 DO BEGIN和END阻止...

我尝试在内部使用/ prompt但它不起作用。

我们还有其他方法可以在postgres中使用函数或块吗?

2 个答案:

答案 0 :(得分:2)

重要提示:PLpgSQL是服务器端语言 - 没有任何可能进行任何用户交互操作。您必须在启动PLpgSQL代码之前在客户端收集输入,并将用户输入作为参数推送到那里。

DO语句是服务器端语句,因此您无法在那里执行任何交互操作。

DO语句不支持参数,因此在DO语句中推送任何参数并不容易,但可以使用自定义配置变量:

\prompt 'enter some text: ' psqlvar
\o /dev/null
select set_config('psql.psqlvar', :'psqlvar', false);
\o
do $$
  DECLARE var text = current_setting('psql.psqlvar');
BEGIN
  RAISE NOTICE 'entered text is: %', var;
END;
$$;

函数set_config用于将客户端变量:psqlvar的内容移动到服务器端 - 会话变量psql.psqlvar。此服务器端变量的内容由函数current_setting获取。

您必须将服务器端和客户端内容分开。 DO语句在服务器端进行评估。 psql \prompt命令在客户端评估。

答案 1 :(得分:1)

由于糟糕的想法,在存储过程中要求用户输入是使用用户名作为会话标识符。这是一个非常非常糟糕的主意。是的,在某些环境中有一些方法可以做到这一点。但仅仅因为你并不意味着你应该这样做。例如,我听说有人使用pl / python将网络连接回客户端计算机并询问更多信息。但是,坦白说这是DailyWTF的领地。它还假定客户端上的协议和监听器要求此请求,因此不能从pgadmin工作。

现在,DO创建一个没有参数的匿名函数并立即执行它。这似乎是你真正的问题所在。

  1. 您最好的解决方案是使用参数创建一个实际函数并接受输入。然后它可以在任何地方使用。并且您可以重复使用,修改安全性等。这听起来就像您需要的那样。

  2. 在发送之前,您无法对using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { var types = new[] { typeof(IEnumerable<int>), typeof(ICollection<int>), typeof(Stack<int>), typeof(IList<int>), typeof(int[]) }; var leaves = types.Where(candidate => !types.Any(t => t != candidate && candidate.IsAssignableFrom(t))); Console.WriteLine(string.Join(Environment.NewLine, leaves)); } } 块进行预处理。

  3. 您想要通过输入重用PL / PGSQL代码的最佳设计是使用函数(请参阅do)而不是CREATE FUNCTION(请注意,如果这是一个函数,您可以将它们放在另一个模式中关注)。