创建一个运行带有用户定义参数的 sql 脚本的 sh 脚本
Posted
技术标签:
【中文标题】创建一个运行带有用户定义参数的 sql 脚本的 sh 脚本【英文标题】:Creating a sh script that runs a sql script with user defined parameters 【发布时间】:2020-07-16 09:19:14 【问题描述】:我是创建 sh 脚本的新手。我正在尝试创建一个 .sh 脚本,该脚本将接受用户输入并通过更新用户给出的参数来执行 SQL 脚本。
用户输入仅限于单个参数。要传递的参数是一个job id -
Enter job id: 321
Confirm job id: 321
这个job id用在SQL代码的不同部分,下面是代码的摘录-
CREATE READABLE EXTERNAL TEMP TABLE JOBID_USER (
cola numeric,
colb bigint,
)
LOCATION (
'gpfdist://.../JOBID_USER_INFO_321.txt' --the job id is at the end of the file
)
FORMAT 'text' (header delimiter e',' null '' escape 'off')
ENCODING 'latin9';
-------------------------------------------------------------------------------------------
CREATE TABLE AS
SELECT * FROM schema.deliverytable_321 -- the job id is used to identify a table
WHERE JOB_ID= 321 -- the job id is used as a condition
AND asset_1 = 9999
DISTRIBUTE RANDOMLY;
数据库是 Postgres,我在 Greenplum 中手动执行脚本。任何帮助,将不胜感激。谢谢。
【问题讨论】:
【参考方案1】:这只是一个简单的想法。 将您的 sql 查询写入名为 sample.sql 的文件或其他文件中:注意:将 JobID 替换为 MY_VAR
CREATE READABLE EXTERNAL TEMP TABLE JOBID_USER (
cola numeric,
colb bigint,
)
LOCATION (
'gpfdist://.../JOBID_USER_INFO_MY_VAR.txt' --the job id is at the end of the file
)
FORMAT 'text' (header delimiter e',' null '' escape 'off')
ENCODING 'latin9';
-------------------------------------------------------------------------------------------
CREATE TABLE AS
SELECT * FROM schema.deliverytable_MY_VAR -- the job id is used to identify a table
WHERE JOB_ID= MY_VAR -- the job id is used as a condition
AND asset_1 = 9999
DISTRIBUTE RANDOMLY;
现在使用这个名为 sql_executor.sh 的脚本:
#!/bin/bash
sed "s/MY_VAR/$1" sample.sql | psql -U [USERNAME] -d [DATABASE_NAME]
用法:
sql_executor.sh 321
【讨论】:
你真的需要echo sample.sql
吗? AFAIN 这将传递 sting 'sample.sql' 而不是文件。我建议让sed
直接打开文件:sed "s/MY_VAR/$1" sample.sql | psql -U [USERNAME] -d [DATABASE_NAME]
。
哦,是的,是的,你说得对。实际上不需要使用 echo 命令。 @BobaFit【参考方案2】:
这是您在 bash 中以交互方式获取输入的方式
#!/bin/bash
printf "Enter job id:"
read -r JOBID
printf "Confirm job id:"
read -r JOBIDCONFIRM
[ "$JOBID" != "$JOBIDCONFIRM" ] &&
echo "Jobid inputs have not the same value"
exit
echo "Now you can use your jobid $JOBID anywhere in double quoted strings, like this sentence"
解释:
printf:回显字符串读取 [varname]:等待用户输入并将其分配给 [varname] 变量
【讨论】:
@franzisk:感谢参数脚本。不过,我可以调用在所有必需位置都包含所有 $JOBID 的 SQL 脚本吗?就像我们通常如何运行 psql 文件 psql /myscript.sql 是的。首先只是回显生成的脚本,以检查一切是否正常。如果可以,那么将您的脚本通过管道传输 pgsql (./script.sh | psql -U [USERNAME] -d [DATABASE_NAME]) 。我的回答只是建议如何向用户询问输入,将其分配给变量,在字符串中使用变量。【参考方案3】:psql 具有可用于参数的“变量”。例如:
cat foo.sql
select :param1
SQL 文件中的冒号表示它是一个变量。
要使用此变量,您只需使用 psql 将值传递给它。
psql -f foo.sql -v param1="'bar'"
?column?
----------
bar
(1 row)
要从 bash 脚本执行此操作,您可以使用 bash 变量。
cat runme.sql
#!/bin/bash
param1="$1"
psql -f foo.sql -v param1="'$param1'"
注意:一定要chmod runme.sql,这样你才能执行它。
chmod 755 runme.sql
现在运行它。
./runme.sql foobar
?column?
----------
foobar
(1 row)
【讨论】:
嗨乔恩,是的,这也有效。不过,我的 sql 脚本有时会将参数嵌套在表名中。例如schema.table432m 其中 432 是参数。然后where colA= 432 and ..
,..create table as job_id432 ...
参数可以放在sql代码中不同的字符串位置。
您可以在 psql 中使用多个变量。 psql -v param1 -v param2 等。所以bash脚本可以创建表名参数,然后将其传递给psql。以上是关于创建一个运行带有用户定义参数的 sql 脚本的 sh 脚本的主要内容,如果未能解决你的问题,请参考以下文章
创建带有 2 个游标、一个参数并从表中给出结果的 PL/SQL 脚本?