admin

如何将变量从外壳脚本传递到sqlplus

sql

我有一个调用file.sql的shell脚本

我正在寻找一种将一些参数传递给我的file.sql的方法。

如果我没有将具有某个值的变量传递给sql脚本,则将不得不使用SELECT语句创建多个.sql文件,并且所有更改将只需要几个字即可。

我的shell脚本调用file.sql:

sqlplus -S user/pass@localhost
echo " Processing triples"
./load_triples.sh BUILDING/Mapping_File BUILDING Y >> load_semantic.log

@/opt/D2RQ/file.sql
exit;
EOF

这就是我的file.sql的样子:

SET ECHO ON;
SPOOL count.log

SELECT COUNT(*) as total_count
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('BUILDING'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

SPOOL OFF;

我可以修改我的shell脚本,以便它传递变量名吗?

即:模型=“建筑”,并将其传递给file.sql?

有没有类似的东西?


阅读 162

收藏
2021-05-10

共1个答案

admin

您似乎只heredoc包含一个SQL * Plus命令,尽管它看起来不像注释中所指出的那样正确。您可以在中传递值heredoc

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql BUILDING
exit;
EOF

或者,如果BUILDING$2在你的脚本:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql $2
exit;
EOF

如果您在末尾file.sql有一个exit,那么它将更加简单,因为您不需要heredoc

sqlplus -S user/pass@localhost @/opt/D2RQ/file.sql $2

然后,在SQL中,您可以使用替换变量来引用位置参数:

...
}',SEM_Models('&1'),NULL,
...

&1将传递到SQL脚本,第一个值来代替BUILDING; 因为那是一个字符串,所以仍然需要用引号将其引起来。set verify off如果在输出中显示替换,您可能想停止。


您可以传递多个值,并像在Shell脚本中的位置参数一样依次引用它们-
第一个传递的参数是&1,第二个传递的参数是&2,等等。您可以在SQL脚本中的任何位置使用替换变量,因此可以使用它们作为列别名没有问题-
您只需要小心添加一个额外的参数,您可以将其添加到列表的末尾(这可能会使脚本中的编号混乱)或调整所有内容以使其匹配:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql total_count BUILDING
exit;
EOF

或者:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql total_count $2
exit;
EOF

如果total_count要传递给您的Shell脚本,则只需使用其positional参数$4或其他任何参数即可。然后您的SQL将是:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&2'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

如果您传递许多值,您可能会发现使用位置参数来定义命名参数更加清晰,因此所有排序问题都在脚本开始时处理,因此更易于维护:

define MY_ALIAS = &1
define MY_MODEL = &2

SELECT COUNT(*) as &MY_ALIAS
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&MY_MODEL'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

从您单独的问题中,也许您只是想要:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&1'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

…,因此别名将是您要查询的值$2(或BUILDING答案原始部分中的值)。您可以根据需要多次引用替换变量。

如果您多次运行它,可能会不容易使用,因为它将在输出的每一位中显示为计数值上方的标头。也许以后会更解析:

select '&1' as QUERIED_VALUE, COUNT(*) as TOTAL_COUNT

如果您set pages 0set heading off,您的重复呼叫可能会显示在整洁的列表中。您可能还需要set tab off并且可能使用rpad('&1', 20)或类似方法使该列始终保持相同的宽度。或通过以下方式以CSV格式获取结果:

select '&1' ||','|| COUNT(*)

取决于您将结果用于…

2021-05-10