创建一个运行带有用户定义参数的 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 脚本?

将参数传递给 oracle 脚本

SQL Server 视图定义

SQL 2008 用户定义函数无法识别

是否有人创建了将十进制数作为参数的雪花用户定义函数 (SQL)?

如何运行带有参数的python脚本?