简体   繁体   English

如何将变量从shell脚本传递给sqlplus

[英]how to pass variable from shell script to sqlplus

I have a shell script that calls file.sql 我有一个调用file.sql的shell脚本

I am looking for a way to pass some parameters to my file.sql. 我正在寻找一种方法将一些参数传递给我的file.sql。

If I don't pass a variable with some value to the sql script, I will have to create multiple .sql files with SELECT statement and all that would change is few words. 如果我没有将带有某些值的变量传递给sql脚本,我将不得不使用SELECT语句创建多个.sql文件,所有改变的是几个单词。

My shell script calls file.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

And this is how my file.sql looks like: 这就是我的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;

Can I modify my shell script so that it passes variable names? 我可以修改我的shell脚本以便它传递变量名吗?

Ie: model = "BUILDING" and pass this on to file.sql? 即:model =“BUILDING”并将其传递给file.sql?

Is there anything like that? 有什么相似的吗?

You appear to have a heredoc containing a single SQL*Plus command, though it doesn't look right as noted in the comments. 您似乎有一个包含单个SQL * Plus命令的heredoc ,但它看起来不正确,如注释中所述。 You can either pass a value in the heredoc : 你可以在heredoc传递一个值:

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

or if BUILDING is $2 in your script: 或者如果您的脚本中的BUILDING$2

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

If your file.sql had an exit at the end then it would be even simpler as you wouldn't need the heredoc : 如果你的file.sql有一个exit ,那么它会更简单,因为你不需要heredoc

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

In your SQL you can then refer to the position parameters using substitution variables : 在SQL中,您可以使用替换变量引用位置参数:

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

The &1 will be replaced with the first value passed to the SQL script, BUILDING ; &1将替换为传递给SQL脚本的第一个值BUILDING ; because that is a string it still needs to be enclosed in quotes. 因为这是一个字符串,它仍然需要用引号括起来。 You might want to set verify off to stop if showing you the substitutions in the output. 如果在输出中显示替换,您可能希望set verify off为停止。


You can pass multiple values, and refer to them sequentially just as you would positional parameters in a shell script - the first passed parameter is &1 , the second is &2 , etc. You can use substitution variables anywhere in the SQL script, so they can be used as column aliases with no problem - you just have to be careful adding an extra parameter that you either add it to the end of the list (which makes the numbering out of order in the script, potentially) or adjust everything to match: 您可以传递多个值,并按顺序引用它们,就像在shell脚本中的位置参数一样 - 第一个传递的参数是&1 ,第二个是&2 ,等等。您可以在SQL脚本的任何位置使用替换变量,这样它们就可以了用作列别名没有问题 - 您只需要小心添加一个额外的参数,您可以将其添加到列表的末尾(这可能会使脚本中的编号失序)或调整所有匹配的参数:

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

or: 要么:

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

If total_count is being passed to your shell script then just use its positional parameter, $4 or whatever. 如果将total_count传递给您的shell脚本,那么只需使用其位置参数$4或其他。 And your SQL would then be: 然后你的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));

If you pass a lot of values you may find it clearer to use the positional parameters to define named parameters, so any ordering issues are all dealt with at the start of the script, where they are easier to maintain: 如果传递了很多值,您可能会发现使用位置参数来定义命名参数更加清晰,因此任何排序问题都会在脚本开头处理,它们更容易维护:

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));

From your separate question, maybe you just wanted: 从你单独的问题,也许你只是想:

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));

... so the alias will be the same value you're querying on (the value in $2 , or BUILDING in the original part of the answer). ...所以别名将与您查询的值相同( $2的值,或者答案原始部分中的BUILDING )。 You can refer to a substitution variable as many times as you want. 您可以根据需要多次引用替换变量。

That might not be easy to use if you're running it multiple times, as it will appear as a header above the count value in each bit of output. 如果你多次运行它可能不容易使用,因为它将在每个输出位的计数值上方显示为标题。 Maybe this would be more parsable later: 也许这会在以后更容易解析:

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

If you set pages 0 and set heading off , your repeated calls might appear in a neat list. 如果您set pages 0 set heading off ,则重复的调用可能会显示在整齐的列表中。 You might also need to set tab off and possibly use rpad('&1', 20) or similar to make that column always the same width. 您可能还需要set tab off并可能使用rpad('&1', 20)或类似设置使该列始终具有相同的宽度。 Or get the results as CSV with: 或者以CSV格式获得结果:

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

Depends what you're using the results for... 取决于您使用的结果...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM