【问题标题】:Creating a sh script that runs a sql script with user defined parameters创建一个运行带有用户定义参数的 sql 脚本的 sh 脚本
【发布时间】: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 中手动执行脚本。任何帮助,将不胜感激。谢谢。

【问题讨论】:

    标签: bash sh 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。
    猜你喜欢
    • 2013-10-24
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2012-08-21
    • 2017-07-30
    相关资源
    最近更新 更多