您好我想从我的用户那里获取输入 DO BEGIN和END阻止...
我尝试在内部使用/ prompt但它不起作用。
我们还有其他方法可以在postgres中使用函数或块吗?
答案 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创建一个没有参数的匿名函数并立即执行它。这似乎是你真正的问题所在。
您最好的解决方案是使用参数创建一个实际函数并接受输入。然后它可以在任何地方使用。并且您可以重复使用,修改安全性等。这听起来就像您需要的那样。
在发送之前,您无法对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));
}
}
块进行预处理。
您想要通过输入重用PL / PGSQL代码的最佳设计是使用函数(请参阅do
)而不是CREATE FUNCTION
(请注意,如果这是一个函数,您可以将它们放在另一个模式中关注)。